source: spip-zone/_plugins_/rainette/trunk/services/wwo.php @ 107740

Last change on this file since 107740 was 107740, checked in by eric@…, 3 years ago

L'API gratuite de WWO n'est plus disponible. Un nouvel endpoint est disponible à la place avec la même API mais nécessite une clé premium avec 60 jours d'essai gratuit. Plutôt que de virer ce service j'ai préféré le conserver puisqu'il fonctionne toujours pour ceux qui peuvent prendre un abonnement.
WWO offre une nouvelle API gratuite du nom APIXU qui fera l'objet d'une mise à jour de Rainette dans quelques temps.

  • Property svn:eol-style set to native
File size: 16.4 KB
Line 
1<?php
2/**
3 * Ce fichier contient la configuration et l'ensemble des fonctions implémentant le service World Weather Online (wwo).
4 * Ce service est capable de fournir des données au format XML ou JSON. Néanmoins, l'API actuelle du plugin utilise
5 * uniquemement le format JSON.
6 *
7 * @package SPIP\RAINETTE\SERVICES\WWO
8 */
9if (!defined('_ECRIRE_INC_VERSION')) {
10        return;
11}
12
13if (!defined('_RAINETTE_WWO_URL_BASE')) {
14        define('_RAINETTE_WWO_URL_BASE', 'http://api.worldweatheronline.com/premium/v1/weather.ashx');
15}
16
17
18// Configuration des valeurs par défaut des éléments de la configuration dynamique.
19// Ces valeurs sont applicables à tous les modes.
20$GLOBALS['rainette_wwo_config']['service'] = array(
21        'alias'   => 'wwo',
22        'defauts' => array(
23                'inscription' => '',
24                'unite'       => 'm',
25                'condition'   => 'wwo',
26                'theme'       => '',
27        ),
28        'credits' => array(
29                'titre'       => 'Free local weather content provider',
30                'logo'        => null,
31                'lien'        => 'http://www.worldweatheronline.com/',
32        ),
33        'langues' => array(
34                'disponibles' => array(
35                        'ar'    => 'ar',
36                        'bg'    => 'bg',
37                        'bn'    => 'bn',
38                        'cs'    => 'cs',
39                        'da'    => 'da',
40                        'de'    => 'de',
41                        'el'    => 'el',
42                        'en'    => 'en',
43                        'es'    => 'es',
44                        'fi'    => 'fi',
45                        'fr'    => 'fr',
46                        'hi'    => 'hi',
47                        'hu'    => 'hu',
48                        'it'    => 'it',
49                        'ja'    => 'ja',
50                        'jv'    => 'jv',
51                        'ko'    => 'ko',
52                        'mr'    => 'mr',
53                        'nl'    => 'nl',
54                        'pa'    => 'pa',
55                        'pl'    => 'pl',
56                        'pt'    => 'pt',
57                        'ro'    => 'ro',
58                        'ru'    => 'ru',
59                        'si'    => 'si',
60                        'sk'    => 'sk',
61                        'sr'    => 'sr',
62                        'sv'    => 'sv',
63                        'ta'    => 'ta',
64                        'te'    => 'te',
65                        'tr'    => 'tr',
66                        'uk'    => 'uk',
67                        'ur'    => 'ur',
68                        'vi'    => 'vi',
69                        'zh'    => 'zh',
70                        'zh_tw' => 'zh_tw',
71                        'zu'    => 'zu',
72                ),
73                'defaut'      => 'en'
74        )
75);
76
77// Configuration des données fournies par le service wwo pour le mode 'infos' en format JSON.
78// -- Seules les données non calculées sont configurées.
79$GLOBALS['rainette_wwo_config']['infos'] = array(
80        'periode_maj' => 86400,
81        'format_flux' => 'json',
82        'cle_base'    => array('data', 'nearest_area', 0),
83        'donnees'     => array(
84                // Lieu
85                'ville'     => array('cle' => array('areaName', 0, 'value')),
86                'pays'      => array('cle' => array('country', 0, 'value')),
87                'pays_iso2' => array('cle' => array()),
88                'region'    => array('cle' => array('region', 0, 'value')),
89                // Coordonnées
90                'longitude' => array('cle' => array('longitude')),
91                'latitude'  => array('cle' => array('latitude')),
92                // Informations complémentaires : aucune configuration car ce sont des données calculées
93        ),
94);
95
96// Configuration des données fournies par le service wwo pour le mode 'conditions'.
97// -- Seules les données non calculées sont configurées.
98$GLOBALS['rainette_wwo_config']['conditions'] = array(
99        'periode_maj' => 10800,
100        'format_flux' => 'json',
101        'cle_base'    => array('data', 'current_condition', 0),
102        'donnees'     => array(
103                // Données d'observation
104                'derniere_maj'          => array('cle' => array('localObsDateTime')),
105                'station'               => array('cle' => array()),
106                // Températures
107                'temperature_reelle'    => array('cle' => array('temp_'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
108                'temperature_ressentie' => array('cle' => array('FeelsLike'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
109                // Données anémométriques
110                'vitesse_vent'          => array('cle' => array('windspeed'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'Kmph', 's' => 'Miles')),
111                'angle_vent'            => array('cle' => array('winddirDegree')),
112                'direction_vent'        => array('cle' => array('winddir16Point')),
113                // Données atmosphériques : risque_uv est calculé
114                'precipitation'         => array('cle' => array('precipMM')),
115                'humidite'              => array('cle' => array('humidity')),
116                'point_rosee'           => array('cle' => array()),
117                'pression'              => array('cle' => array('pressure')),
118                'tendance_pression'     => array('cle' => array()),
119                'visibilite'            => array('cle' => array('visibility')),
120                'indice_uv'             => array('cle' => array()),
121                // Etats météorologiques natifs
122                'code_meteo'            => array('cle' => array('weatherCode')),
123                'icon_meteo'            => array('cle' => array('weatherIconUrl', 0, 'value')),
124                'desc_meteo'            => array('cle' => array('weatherDesc', 0, 'value')),
125                'trad_meteo'            => array('cle' => array('lang_', 0, 'value'), 'suffixe_langue' => array('id_cle' => 0)),
126                // Etats météorologiques calculés : icone, resume, periode sont calculés
127        ),
128);
129
130// Configuration des données fournies par le service wwo pour le mode 'conditions'.
131// -- L'API gratuite fournit 5 jours de prévisions alors que l'API Premium fournit 15 jours
132//    de prévisions. On utilise donc le max des deux.
133// -- Seules les données non calculées sont configurées.
134$GLOBALS['rainette_wwo_config']['previsions'] = array(
135        'periodicites'       => array(
136                24 => array('max_jours' => 15),
137                12 => array('max_jours' => 15),
138                6  => array('max_jours' => 15),
139                3  => array('max_jours' => 15),
140                1  => array('max_jours' => 15)
141        ),
142        'periodicite_defaut' => 24,
143        'periode_maj'        => 14400,
144        'format_flux'        => 'json',
145        'cle_base'           => array('data', 'weather'),
146        'cle_heure'          => array('hourly'),
147        'structure_heure'    => true,
148        'donnees'            => array(
149                // Données d'observation
150                'date'                 => array('cle' => array('date')),
151                'heure'                => array('cle' => array('time')),
152                // Données astronomiques
153                'lever_soleil'         => array('cle' => array('astronomy', 0, 'sunrise')),
154                'coucher_soleil'       => array('cle' => array('astronomy', 0, 'sunset')),
155                // Températures
156                'temperature'          => array('cle' => array('temp'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
157                'temperature_max'      => array('cle' => array('maxtemp'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
158                'temperature_min'      => array('cle' => array('mintemp'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
159                // Données anémométriques
160                'vitesse_vent'         => array('cle' => array('windspeed'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'Kmph', 's' => 'Miles')),
161                'angle_vent'           => array('cle' => array('winddirDegree')),
162                'direction_vent'       => array('cle' => array('winddir16Point')),
163                // Données atmosphériques : risque_uv est calculé
164                'risque_precipitation' => array('cle' => array('chanceofrain')),
165                'precipitation'        => array('cle' => array('precipMM')),
166                'humidite'             => array('cle' => array('humidity')),
167                'point_rosee'          => array('cle' => array('DewPoint'), 'suffixe_unite' => array('id_cle' => 0, 'm' => 'C', 's' => 'F')),
168                'pression'             => array('cle' => array('pressure')),
169                'visibilite'           => array('cle' => array('visibility')),
170                'indice_uv'            => array('cle' => array('uvIndex')),
171                // Etats météorologiques natifs
172                'code_meteo'           => array('cle' => array('weatherCode')),
173                'icon_meteo'           => array('cle' => array('weatherIconUrl', 0, 'value')),
174                'desc_meteo'           => array('cle' => array('weatherDesc', 0, 'value')),
175                'trad_meteo'           => array('cle' => array('lang_', 0, 'value'), 'suffixe_langue' => array('id_cle' => 0)),
176                // Etats météorologiques calculés : icone, resume, periode sont calculés
177        ),
178);
179
180
181// ------------------------------------------------------------------------------------------------
182// Les fonctions qui suivent définissent l'API standard du service et sont appelées par la fonction
183// unique de chargement des données météorologiques `charger_meteo()`.
184// ------------------------------------------------------------------------------------------------
185
186/**
187 * Fournit la configuration statique du service pour le type de données requis.
188 *
189 * @api
190 *
191 * @param string $mode
192 *        Type de données météorologiques. Les valeurs possibles sont `infos`, `conditions` ou `previsions`.
193 *        La périodicité n'est pas nécessaire car la configuration est indifférente à ce paramètre.
194 *
195 * @return array
196 *        Le tableau des données de configuration communes au service et propres au type de données demandé.
197 */
198function wwo_service2configuration($mode) {
199        // On merge la configuration propre au mode et la configuration du service proprement dite
200        // composée des valeurs par défaut de la configuration utilisateur et de paramètres généraux.
201        $config = array_merge($GLOBALS['rainette_wwo_config'][$mode], $GLOBALS['rainette_wwo_config']['service']);
202
203        return $config;
204}
205
206
207/**
208 * Construit l'url de la requête correspondant au lieu, au type de données et à la configuration utilisateur
209 * du service (par exemple, le code d'inscription, le format des résultats...).
210 *
211 * @api
212 * @uses langue2code_wwo()
213 *
214 * @param string $lieu
215 *        Lieu pour lequel on acquiert les données météorologiques.
216 * @param string $mode
217 *        Type de données météorologiques. Les valeurs possibles sont `infos`, `conditions` ou `previsions`.
218 * @param int    $periodicite
219 *        La périodicité horaire des prévisions :
220 *        - `24`, `12`, `6`, `3` ou `1`, pour le mode `previsions`
221 *        - `0`, pour les modes `conditions` et `infos`
222 * @param array  $configuration
223 *        Configuration complète du service, statique et utilisateur.
224 *
225 * @return string
226 *        URL complète de la requête.
227 */
228function wwo_service2url($lieu, $mode, $periodicite, $configuration) {
229
230        // Identification de la langue du resume.
231        include_spip('inc/rainette_normaliser');
232        $code_langue = trouver_langue_service($configuration);
233
234        // On normalise le lieu et on récupère son format.
235        // Le service accepte la format ville,pays, le format latitude,longitude et le format adresse IP.
236        // Néanmoins, la query a toujours la même forme; il n'est donc pas nécessaire de gérer le format.
237        list($lieu_normalise,) = normaliser_lieu($lieu);
238
239        $url = _RAINETTE_WWO_URL_BASE
240                   . '?key=' . $configuration['inscription']
241                   . '&format=' . $configuration['format_flux']
242                   . '&extra=localObsTime'
243                   . '&lang=' . $code_langue
244                   . '&q=' . $lieu_normalise;
245
246        if ($mode == 'infos') {
247                $url .= '&includeLocation=yes&cc=no&fx=no';
248        } elseif ($mode == 'conditions') {
249                $url .= '&cc=yes&fx=no';
250        } else {
251                $url .= '&cc=no&fx=yes'
252                                . '&num_of_days=' . $configuration['periodicites'][$periodicite]['max_jours']
253                                . '&tp=' . strval($periodicite);
254        }
255
256        return $url;
257}
258
259
260/**
261 * Complète par des données spécifiques au service le tableau des conditions issu
262 * uniquement de la lecture du flux.
263 *
264 * @api
265 *
266 * @param array $tableau
267 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
268 *        par le service.
269 * @param array $configuration
270 *        Configuration complète du service, statique et utilisateur.
271 *
272 * @return array
273 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
274 *        du service.
275 */
276function wwo_complement2conditions($tableau, $configuration) {
277
278        if ($tableau) {
279                // Convertir les informations exprimées en système métrique dans le systeme US si la
280                // configuration le demande
281                if ($configuration['unite'] == 's') {
282                        metrique2imperial_wwo($tableau);
283                }
284
285                // Compléter le tableau standard avec les états météorologiques calculés
286                etat2resume_wwo($tableau, $configuration);
287        }
288
289        return $tableau;
290}
291
292
293/**
294 * Complète par des données spécifiques au service le tableau des conditions issu
295 * uniquement de la lecture du flux.
296 *
297 * @api
298 *
299 * @param array $tableau
300 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
301 *        par le service.
302 * @param array $configuration
303 *        Configuration complète du service, statique et utilisateur.
304 * @param int   $index_periode
305 *        Index où trouver et ranger les données. Cet index n'est pas utilisé pour les conditions
306 *
307 * @return array
308 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
309 *        du service.
310 */
311function wwo_complement2previsions($tableau, $configuration, $index_periode) {
312
313        if (($tableau) and ($index_periode > -1)) {
314                // Convertir les informations exprimées en système métrique dans le systeme US si la
315                // configuration le demande
316                if ($configuration['unite'] == 's') {
317                        metrique2imperial_wwo($tableau);
318                }
319
320                // Compléter le tableau standard avec les états météorologiques calculés
321                etat2resume_wwo($tableau, $configuration);
322        }
323
324        return $tableau;
325}
326
327
328// ---------------------------------------------------------------------------------------------
329// Les fonctions qui suivent sont des utilitaires utilisés uniquement appelées par les fonctions
330// de l'API.
331// PACKAGE SPIP\RAINETTE\WWO\OUTILS
332// ---------------------------------------------------------------------------------------------
333
334/**
335 * @param array $tableau
336 *
337 * @return void
338 */
339function metrique2imperial_wwo(&$tableau) {
340        include_spip('inc/rainette_convertir');
341
342        // Seules la température, la température ressentie et la vitesse du vent sont fournies dans
343        // les deux systèmes.
344        // Etant donnée que les tableaux sont normalisés, ils contiennent toujours les index de chaque
345        // donnée météo, il est donc inutile de tester leur existence.
346        $tableau['visibilite'] = ($tableau['visibilite'])
347                ? kilometre2mile($tableau['visibilite'])
348                : '';
349        $tableau['pression'] = ($tableau['pression'])
350                ? millibar2inch($tableau['pression'])
351                : '';
352        $tableau['precipitation'] = ($tableau['precipitation'])
353                ? millimetre2inch($tableau['precipitation'])
354                : '';
355}
356
357
358function etat2resume_wwo(&$tableau, $configuration) {
359
360        if ($tableau['code_meteo'] and $tableau['icon_meteo']) {
361                // Determination de l'indicateur jour/nuit qui permet de choisir le bon icone
362                // Pour ce service aucun indicateur n'est disponible
363                // -> on utilise le nom de l'icone qui contient l'indication "night" pour la nuit
364                $icone = basename($tableau['icon_meteo']);
365                if (strpos($icone, '_night') === false) {
366                        // C'est le jour
367                        $tableau['periode'] = 0;
368                } else {
369                        // C'est la nuit
370                        $tableau['periode'] = 1;
371                }
372
373                // Determination, suivant le mode choisi, du code, de l'icone et du resume qui seront affiches
374                if ($configuration['condition'] == $configuration['alias']) {
375                        // On affiche les conditions natives fournies par le service.
376                        // Pour le resume, wwo fournit la traduction dans un item différent que pour les autres services.
377                        // Cet item est stocké dans trad_meteo.
378                        $tableau['icone']['code'] = $tableau['code_meteo'];
379                        $tableau['icone']['url'] = copie_locale($tableau['icon_meteo']);
380                        $tableau['resume'] = ucfirst($tableau['trad_meteo']);
381                } else {
382                        // On affiche les conditions traduites dans le systeme weather.com
383                        $meteo = meteo_wwo2weather($tableau['code_meteo'], $tableau['periode']);
384                        $tableau['icone'] = $meteo;
385                        $tableau['resume'] = $meteo;
386                }
387        }
388}
389
390
391/**
392 * @internal
393 *
394 * @link http://plugins.trac.wordpress.org/browser/weather-and-weather-forecast-widget/trunk/gg_funx_.php
395 * Transcodage issu du plugin Wordpress weather forecast.
396 *
397 * @param string $meteo
398 * @param int    $periode
399 *
400 * @return string
401 */
402function meteo_wwo2weather($meteo, $periode = 0) {
403        static $wwo2weather = array(
404                395 => array(41, 46),
405                392 => array(41, 46),
406                389 => array(38, 47),
407                386 => array(37, 47),
408                377 => array(6, 6),
409                374 => array(6, 6),
410                371 => array(14, 14),
411                368 => array(13, 13),
412                365 => array(6, 6),
413                362 => array(6, 6),
414                359 => array(11, 11),
415                356 => array(11, 11),
416                353 => array(9, 9),
417                350 => array(18, 18),
418                338 => array(16, 16),
419                335 => array(16, 16),
420                332 => array(14, 14),
421                329 => array(14, 14),
422                326 => array(13, 13),
423                323 => array(13, 13),
424                320 => array(18, 18),
425                317 => array(18, 18),
426                314 => array(8, 8),
427                311 => array(8, 8),
428                308 => array(40, 40),
429                305 => array(39, 45),
430                302 => array(11, 11),
431                299 => array(39, 45),
432                296 => array(9, 9),
433                293 => array(9, 9),
434                284 => array(10, 10),
435                281 => array(9, 9),
436                266 => array(9, 9),
437                263 => array(9, 9),
438                260 => array(20, 20),
439                248 => array(20, 20),
440                230 => array(16, 16),
441                227 => array(15, 15),
442                200 => array(38, 47),
443                185 => array(10, 10),
444                182 => array(18, 18),
445                179 => array(16, 16),
446                176 => array(40, 49),
447                143 => array(20, 20),
448                122 => array(26, 26),
449                119 => array(28, 27),
450                116 => array(30, 29),
451                113 => array(32, 31)
452        );
453
454        $icone = 'na';
455        if (array_key_exists($meteo, $wwo2weather)) {
456                $icone = strval($wwo2weather[$meteo][$periode]);
457        }
458
459        return $icone;
460}
Note: See TracBrowser for help on using the repository browser.