source: spip-zone/_plugins_/rainette/trunk/services/owm.php @ 108190

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

Pour Wunderground:

  • Correction du calcul de l'url de l'icone .
  • ajout d'un cas de tendance de pression pour éviter une notice. Ce cas est traité pour l'instant comme une erreur et la tendance n'est pas affichée.

Début de mise à jour du transcodage de owm vers weather.

  • Property svn:eol-style set to native
File size: 16.7 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des constantes et fonctions implémentant le service Open Weather Map (owm).
4 * Ce service fournit des données au format XML ou JSON mais Rainette utilise uniquement le JSON.
5 *
6 * @package SPIP\RAINETTE\SERVICES\OWM
7 */
8if (!defined('_ECRIRE_INC_VERSION')) {
9        return;
10}
11
12if (!defined('_RAINETTE_OWM_URL_BASE_REQUETE')) {
13        define('_RAINETTE_OWM_URL_BASE_REQUETE', 'http://api.openweathermap.org/data/2.5/');
14}
15if (!defined('_RAINETTE_OWM_URL_BASE_ICONE')) {
16        define('_RAINETTE_OWM_URL_BASE_ICONE', 'http://openweathermap.org/img/w');
17}
18
19
20// Configuration des valeurs par défaut des éléments de la configuration dynamique.
21// Ces valeurs sont applicables à tous les modes.
22$GLOBALS['rainette_owm_config']['service'] = array(
23        'alias'          => 'owm',
24        'nom'            => 'OpenWeatherMap',
25        'credits'        => array(
26                'titre' => null,
27                'logo'  => null,
28                'lien'  => 'http://openweathermap.org/',
29        ),
30        'termes'         => array(
31                'titre' => 'Terms of service',
32                'lien'  => 'http://openweathermap.org/terms'
33        ),
34        'enregistrement' => array(
35                'titre'      => 'Members',
36                'lien'       => 'https://home.openweathermap.org/users/sign_up',
37                'taille_cle' => 32
38        ),
39        'offres'         => array(
40                'titre'   => 'Price',
41                'lien'    => 'https://openweathermap.org/price',
42                'limites' => array(
43                        'minute' => 60
44                ),
45        ),
46        'langues'        => array(
47                'disponibles' => array(
48                        'bg'    => 'bg',
49                        'ca'    => 'ca',
50                        'de'    => 'de',
51                        'en'    => 'en',
52                        'es'    => 'es',
53                        'fi'    => 'fi',
54                        'fr'    => 'fr',
55                        'hr'    => 'hr',
56                        'it'    => 'it',
57                        'nl'    => 'nl',
58                        'pl'    => 'pl',
59                        'pt'    => 'pt',
60                        'ro'    => 'ro',
61                        'ru'    => 'ru',
62                        'sv'    => 'sv',
63                        'tr'    => 'tr',
64                        'uk'    => 'uk',
65                        'zh'    => 'zh',
66                        'zh_tw' => 'zh_tw',
67                ),
68                'defaut'      => 'en'
69        ),
70        'defauts'        => array(
71                'inscription' => '',
72                'unite'       => 'm',
73                'condition'   => 'owm',
74                'theme'       => '',
75        )
76);
77
78// Configuration des données fournies par le service owm pour le mode 'infos'.
79// -- Seules les données non calculées sont configurées.
80$GLOBALS['rainette_owm_config']['infos'] = array(
81        'periode_maj' => 3600 * 24 * 30,
82        'format_flux' => 'json',
83        'cle_base'    => array(),
84        'donnees'     => array(
85                // Lieu
86                'ville'     => array('cle' => array('name')),
87                'pays'      => array('cle' => array()),
88                'pays_iso2' => array('cle' => array('sys', 'country')),
89                'region'    => array('cle' => array()),
90                // Coordonnées
91                'longitude' => array('cle' => array('coord', 'lon')),
92                'latitude'  => array('cle' => array('coord', 'lat')),
93                // Informations complémentaires : aucune configuration car ce sont des données calculées
94        ),
95);
96
97// Configuration des données fournies par le service owm pour le mode 'conditions'.
98// -- Seules les données non calculées sont configurées.
99$GLOBALS['rainette_owm_config']['conditions'] = array(
100        'periode_maj' => 3600 * 2,
101        'format_flux' => 'json',
102        'cle_base'    => array(),
103        'donnees'     => array(
104                // Données d'observation
105                'derniere_maj'          => array('cle' => array('dt')),
106                'station'               => array('cle' => array()),
107                // Températures
108                'temperature_reelle'    => array('cle' => array('main', 'temp')),
109                'temperature_ressentie' => array('cle' => array()),
110                // Données anémométriques
111                'vitesse_vent'          => array('cle' => array('wind', 'speed')),
112                'angle_vent'            => array('cle' => array('wind', 'deg')),
113                'direction_vent'        => array('cle' => array()),
114                // Données atmosphériques : risque_uv est calculé
115                'precipitation'         => array('cle' => array()),
116                'humidite'              => array('cle' => array('main', 'humidity')),
117                'point_rosee'           => array('cle' => array()),
118                'pression'              => array('cle' => array('main', 'pressure')),
119                'tendance_pression'     => array('cle' => array()),
120                'visibilite'            => array('cle' => array('visibility')),
121                'indice_uv'             => array('cle' => array()),
122                // Etats météorologiques natifs
123                'code_meteo'            => array('cle' => array('weather', 0, 'id')),
124                'icon_meteo'            => array('cle' => array('weather', 0, 'icon')),
125                'desc_meteo'            => array('cle' => array('weather', 0, 'description')),
126                'trad_meteo'            => array('cle' => array()),
127                // Etats météorologiques calculés : icone, resume, periode sont calculés
128        ),
129);
130
131// Configuration des données fournies par le service owm pour le mode 'conditions'.
132// -- Seules les données non calculées sont configurées.
133$GLOBALS['rainette_owm_config']['previsions'] = array(
134        'periodicites'       => array(
135                24 => array('max_jours' => 16),
136                //              3                      => array('max_jours' => 5)
137        ),
138        'periodicite_defaut' => 24,
139        'periode_maj'        => 3600 * 2,
140        'format_flux'        => 'json',
141        'cle_base'           => array('list'),
142        'cle_heure'          => array(),
143        'structure_heure'    => false,
144        'donnees'            => array(
145                // Données d'observation
146                'date'                 => array('cle' => array('dt')),
147                'heure'                => array('cle' => array()),
148                // Données astronomiques
149                'lever_soleil'         => array('cle' => array()),
150                'coucher_soleil'       => array('cle' => array()),
151                // Températures
152                'temperature'          => array('cle' => array()),
153                'temperature_max'      => array('cle' => array('temp', 'max')),
154                'temperature_min'      => array('cle' => array('temp', 'min')),
155                // Données anémométriques
156                'vitesse_vent'         => array('cle' => array('speed')),
157                'angle_vent'           => array('cle' => array('deg')),
158                'direction_vent'       => array('cle' => array()),
159                // Données atmosphériques : risque_uv est calculé
160                'risque_precipitation' => array('cle' => array()),
161                'precipitation'        => array('cle' => array('rain')),
162                'humidite'             => array('cle' => array('humidity')),
163                'point_rosee'          => array('cle' => array()),
164                'pression'             => array('cle' => array('pressure')),
165                'visibilite'           => array('cle' => array()),
166                'indice_uv'            => array('cle' => array()),
167                // Etats météorologiques natifs
168                'code_meteo'           => array('cle' => array('weather', 0, 'id')),
169                'icon_meteo'           => array('cle' => array('weather', 0, 'icon')),
170                'desc_meteo'           => array('cle' => array('weather', 0, 'description')),
171                'trad_meteo'           => array('cle' => array()),
172                // Etats météorologiques calculés : icone, resume, periode sont calculés
173        ),
174);
175
176// Configuration des données fournies par le service owm en cas d'erreur.
177// -- Seules les données non calculées sont configurées.
178$GLOBALS['rainette_owm_config']['erreurs'] = array(
179        'cle_base' => array(),
180        'donnees'  => array(
181                // Erreur
182                'code'    => array('cle' => array('cod')),
183                'message' => array('cle' => array('message')),
184        ),
185);
186
187
188/**
189 * ------------------------------------------------------------------------------------------------
190 * Les fonctions qui suivent définissent l'API standard du service et sont appelées par la fonction
191 * unique de chargement des données météorologiques `meteo_charger()`.
192 * PACKAGE SPIP\RAINETTE\OWM\API
193 * ------------------------------------------------------------------------------------------------
194 *
195 * @param mixed $mode
196 */
197
198/**
199 * @param string $mode
200 *
201 * @return array
202 */
203function owm_service2configuration($mode) {
204        // On merge la configuration propre au mode et la configuration du service proprement dit
205        // composée des valeurs par défaut de la configuration utilisateur et de paramètres généraux.
206        $config = array_merge($GLOBALS['rainette_owm_config'][$mode], $GLOBALS['rainette_owm_config']['service']);
207
208        return $config;
209}
210
211
212/**
213 * @param $lieu
214 * @param $mode
215 * @param $periodicite
216 * @param $configuration
217 *
218 * @return string
219 */
220function owm_service2url($lieu, $mode, $periodicite, $configuration) {
221
222        // Determination de la demande
223        $demande = ($mode == 'previsions') ? 'forecast' : 'weather';
224        if ($periodicite == 24) {
225                $demande .= '/daily';
226        }
227
228        // Identification de la langue du resume.
229        // Le choix de la langue n'a d'interet que si on utilise le resume natif du service. Si ce n'est pas le cas
230        // on ne la precise pas et on laisse l'API renvoyer la langue par defaut
231        include_spip('inc/rainette_normaliser');
232        $code_langue = langue_determiner($configuration);
233
234        // On normalise le lieu et on récupère son format.
235        // Le service accepte la format ville,pays et le format latitude,longitude
236        $lieu_normalise = lieu_normaliser($lieu, $format_lieu);
237        if ($format_lieu == 'latitude_longitude') {
238                list($latitude, $longitude) = explode(',', $lieu_normalise);
239                $query = "lat=${latitude}&lon=${longitude}";
240        } else {
241                // Format ville,pays
242                $query = "q=${lieu_normalise}";
243        }
244
245        $url = _RAINETTE_OWM_URL_BASE_REQUETE
246                   . $demande . '?'
247                   . $query
248                   . '&mode=' . $configuration['format_flux']
249                   . '&units=' . ($configuration['unite'] == 'm' ? 'metric' : 'imperial')
250                   . ((($mode == 'previsions') and ($periodicite == 24))
251                        ? '&cnt=' . $configuration['periodicites'][$periodicite]['max_jours']
252                        : '')
253                   . '&lang=' . $code_langue
254                   . ($configuration['inscription'] ? '&APPID=' . $configuration['inscription'] : '');
255
256        return $url;
257}
258
259
260/**
261 * @param array $erreur
262 *
263 * @return bool
264 */
265function owm_erreur_verifier($erreur) {
266
267        // Initialisation
268        $est_erreur = false;
269
270        // Pour OWM une erreur possède deux attributs, le code et le message.
271        // Néanmoins, le code 200 est aussi renvoyé pour dire ok sans message.
272        // => il faut donc écarter ce cas d'une erreur.
273        if (!empty($erreur['code']) and !empty($erreur['message']) and ($erreur['code'] != '200')) {
274                $est_erreur = true;
275        }
276
277        return $est_erreur;
278}
279
280
281/**
282 * @param array $tableau
283 * @param       $configuration
284 *
285 * @return array
286 */
287function owm_complement2infos($tableau, $configuration) {
288        // Aucune donnée à rajouter en complément au tableau initialisé
289        // TODO : remplir le nom du pays à partir du code ISO 3166-1 alpha 2.
290        return $tableau;
291}
292
293
294/**
295 * Complète par des données spécifiques au service le tableau des conditions issu
296 * uniquement de la lecture du flux.
297 *
298 * @api
299 *
300 * @param array $tableau
301 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
302 *        par le service.
303 * @param array $configuration
304 *        Configuration complète du service, statique et utilisateur.
305 *
306 * @return array
307 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
308 *        du service.
309 */
310function owm_complement2conditions($tableau, $configuration) {
311
312        if ($tableau) {
313                // Calcul de la température ressentie et de la direction du vent (16 points), celles-ci
314                // n'étant pas fournie nativement par owm
315                include_spip('inc/rainette_convertir');
316                $tableau['temperature_ressentie'] = temperature2ressenti($tableau['temperature_reelle'], $tableau['vitesse_vent']);
317                $tableau['direction_vent'] = angle2direction($tableau['angle_vent']);
318                // On convertit aussi la visibilité en km car elle est fournie en mètres.
319                $tableau['visibilite'] = metre2kilometre($tableau['visibilite']);
320
321                // Compléter le tableau standard avec les états météorologiques calculés
322                etat2resume_owm($tableau, $configuration);
323        }
324
325        return $tableau;
326}
327
328
329/**
330 * Complète par des données spécifiques au service le tableau des conditions issu
331 * uniquement de la lecture du flux.
332 *
333 * @api
334 *
335 * @param array $tableau
336 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
337 *        par le service.
338 * @param array $configuration
339 *        Configuration complète du service, statique et utilisateur.
340 * @param int   $index_periode
341 *        Index où trouver et ranger les données. Cet index n'est pas utilisé pour les conditions
342 *
343 * @return array
344 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
345 *        du service.
346 */
347function owm_complement2previsions($tableau, $configuration, $index_periode) {
348
349        if (($tableau) and ($index_periode > -1)) {
350                // Vérifier les précipitations. Pour les prévisions, OWM renvoie le champ rain uniquement si il est
351                // différent de zéro. Il faut donc rétablir la valeur zéro dans ce cas pour éviter d'avoir N/D lors de
352                // l'affichage.
353                if ($tableau['precipitation'] === '') {
354                        $tableau['precipitation'] = 0;
355                }
356
357                // Compléter le tableau standard avec les états météorologiques calculés
358                etat2resume_owm($tableau, $configuration);
359        }
360
361        return $tableau;
362}
363
364
365/**
366 * ---------------------------------------------------------------------------------------------
367 * Les fonctions qui suivent sont des utilitaires utilisés uniquement appelées par les fonctions
368 * de l'API.
369 * PACKAGE SPIP\RAINETTE\OWM\OUTILS
370 * ---------------------------------------------------------------------------------------------
371 *
372 * @param mixed $configuration
373 */
374
375/**
376 * Calcule les états en fonction des états météorologiques natifs fournis par le service.
377 *
378 * @internal
379 *
380 * @param array $tableau
381 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
382 *        par le service. Le tableau est mis à jour et renvoyé à l'appelant.
383 * @param array $configuration
384 *        Configuration complète du service, statique et utilisateur.
385 *
386 * @return void
387 */
388function etat2resume_owm(&$tableau, $configuration) {
389
390        if ($tableau['code_meteo'] and $tableau['icon_meteo']) {
391                // Determination de l'indicateur jour/nuit qui permet de choisir le bon icone
392                // Pour ce service le nom du fichier icone finit par "d" pour le jour et
393                // par "n" pour la nuit.
394                $icone = $tableau['icon_meteo'];
395                if (strpos($icone, 'n') === false) {
396                        // C'est le jour
397                        $tableau['periode'] = 0;
398                } else {
399                        // C'est la nuit
400                        $tableau['periode'] = 1;
401                }
402
403                // Determination, suivant le mode choisi, du code, de l'icone et du resume qui seront affiches
404                if ($configuration['condition'] == $configuration['alias']) {
405                        // On affiche les conditions natives fournies par le service.
406                        // Celles-ci etant deja traduites dans la bonne langue on stocke le texte exact retourne par l'API
407                        $tableau['icone']['code'] = $tableau['code_meteo'];
408                        $url = _RAINETTE_OWM_URL_BASE_ICONE . '/' . $tableau['icon_meteo'] . '.png';
409                        $tableau['icone']['url'] = copie_locale($url);
410                        $tableau['resume'] = ucfirst($tableau['desc_meteo']);
411                } else {
412                        // On affiche les conditions traduites dans le systeme weather.com
413                        // Pour le resume on stocke le code et non la traduction pour eviter de generer
414                        // un cache par langue comme pour le mode natif. La traduction est faite via les fichiers de langue
415                        $meteo = meteo_owm2weather($tableau['code_meteo'], $tableau['periode']);
416                        $tableau['icone'] = $meteo;
417                        $tableau['resume'] = $meteo;
418                }
419        }
420}
421
422
423// TODO : mettre au point le transcodage omw vers weather
424function meteo_owm2weather($meteo, $periode = 0) {
425        static $owm2weather = array(
426                '200' => array(41, 46),
427                '201' => array(39, 45),
428                '202' => array(39, 45),
429                '210' => array(41, 46),
430                '211' => array(38, 47),
431                '212' => array(32, 31),
432                '221' => array(26, 26),
433                '230' => array(15, 15),
434                '231' => array(20, 20),
435                '232' => array(21, 21),
436                '300' => array(28, 27),
437                '301' => array(34, 33),
438                '302' => array(30, 29),
439                '310' => array(28, 27),
440                '311' => array(5, 5),
441                '312' => array(11, 11),
442                '313' => array(16, 16),
443                '314' => array(32, 31),
444                '321' => array(4, 4),
445                '500' => array(4, 4),
446                '501' => array(4, 4),
447                '502' => array(30, 29),
448                '503' => array(26, 26),
449                '504' => array(26, 26),
450                '511' => array(26, 26),
451                '520' => array(26, 26),
452                '521' => array(26, 26),
453                '522' => array(26, 26),
454                '531' => array(26, 26),
455                '600' => array(26, 26),
456                '601' => array(26, 26),
457                '602' => array(26, 26),
458                '611' => array(26, 26),
459                '612' => array(26, 26),
460                '615' => array(26, 26),
461                '616' => array(26, 26),
462                '620' => array(26, 26),
463                '621' => array(26, 26),
464                '622' => array(26, 26),
465                '701' => array(26, 26),
466                '711' => array(26, 26),
467                '721' => array(26, 26),
468                '731' => array(26, 26),
469                '741' => array(26, 26),
470                '751' => array(26, 26),
471                '761' => array(26, 26),
472                '762' => array(26, 26),
473                '771' => array(26, 26),
474                '781' => array(26, 26),
475                '800' => array(26, 26),
476                '801' => array(26, 26),
477                '802' => array(26, 26),
478                '803' => array(26, 26),
479                '804' => array(26, 26),
480                '900' => array(0, 0),
481                '901' => array(26, 26),
482                '902' => array(26, 26),
483                '903' => array(26, 26),
484                '904' => array(26, 26),
485                '905' => array(26, 26),
486                '906' => array(26, 26),
487                '951' => array(26, 26),
488                '952' => array(26, 26),
489                '953' => array(26, 26),
490                '954' => array(26, 26),
491                '955' => array(26, 26),
492                '956' => array(26, 26),
493                '957' => array(26, 26),
494                '958' => array(26, 26),
495                '959' => array(26, 26),
496                '960' => array(26, 26),
497                '961' => array(26, 26),
498                '962' => array(26, 26)
499        );
500
501        $icone = 'na';
502        if (array_key_exists($meteo, $owm2weather)) {
503                $icone = strval($owm2weather[$meteo][$periode]);
504        }
505
506        return $icone;
507}
Note: See TracBrowser for help on using the repository browser.