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

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

Fin de la mise au point du service weatherbit.io et refactoring complet de la configuration des services. Pour la peine un up de y.

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