source: spip-zone/_plugins_/rainette/trunk/services/owm.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: 15.5 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
196/**
197 * @param string $mode
198 *
199 * @return array
200 */
201function owm_service2configuration($mode) {
202        // On merge la configuration propre au mode et la configuration du service proprement dit
203        // composée des valeurs par défaut de la configuration utilisateur et de paramètres généraux.
204        $config = array_merge($GLOBALS['rainette_owm_config'][$mode], $GLOBALS['rainette_owm_config']['service']);
205
206        return $config;
207}
208
209
210/**
211 * @param $lieu
212 * @param $mode
213 * @param $periodicite
214 * @param $configuration
215 *
216 * @return string
217 */
218function owm_service2url($lieu, $mode, $periodicite, $configuration) {
219
220        // Determination de la demande
221        $demande = ($mode == 'previsions') ? 'forecast' : 'weather';
222        if ($periodicite == 24) {
223                $demande .= '/daily';
224        }
225
226        // Identification de la langue du resume.
227        // 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
228        // on ne la precise pas et on laisse l'API renvoyer la langue par defaut
229        include_spip('inc/rainette_normaliser');
230        $code_langue = langue_determiner($configuration);
231
232        // On normalise le lieu et on récupère son format.
233        // Le service accepte la format ville,pays et le format latitude,longitude
234        $lieu_normalise = lieu_normaliser($lieu, $format_lieu);
235        if ($format_lieu == 'latitude_longitude') {
236                list($latitude, $longitude) = explode(',', $lieu_normalise);
237                $query = "lat=${latitude}&lon=${longitude}";
238        } else {
239                // Format ville,pays
240                $query = "q=${lieu_normalise}";
241        }
242
243        $url = _RAINETTE_OWM_URL_BASE_REQUETE
244                   . $demande . '?'
245                   . $query
246                   . '&mode=' . $configuration['format_flux']
247                   . '&units=' . ($configuration['unite'] == 'm' ? 'metric' : 'imperial')
248                   . ((($mode == 'previsions') and ($periodicite == 24))
249                        ? '&cnt=' . $configuration['periodicites'][$periodicite]['max_jours']
250                        : '')
251                   . '&lang=' . $code_langue
252                   . ($configuration['inscription'] ? '&APPID=' . $configuration['inscription'] : '');
253
254        return $url;
255}
256
257
258/**
259 * @param array $erreur
260 *
261 * @return bool
262 */
263function owm_erreur_verifier($erreur) {
264
265        // Initialisation
266        $est_erreur = false;
267
268        // Pour OWM une erreur possède deux attributs, le code et le message.
269        // Néanmoins, le code 200 est aussi renvoyé pour dire ok sans message.
270        // => il faut donc écarter ce cas d'une erreur.
271        if (!empty($erreur['code']) and !empty($erreur['message']) and ($erreur['code'] != '200')) {
272                $est_erreur = true;
273        }
274
275        return $est_erreur;
276}
277
278
279/**
280 * @param array $tableau
281 * @param       $configuration
282 *
283 * @return array
284 */
285function owm_complement2infos($tableau, $configuration) {
286        // Aucune donnée à rajouter en complément au tableau initialisé
287        // TODO : remplir le nom du pays à partir du code ISO 3166-1 alpha 2.
288        return $tableau;
289}
290
291
292/**
293 * Complète par des données spécifiques au service le tableau des conditions issu
294 * uniquement de la lecture du flux.
295 *
296 * @api
297 *
298 * @param array $tableau
299 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
300 *        par le service.
301 * @param array $configuration
302 *        Configuration complète du service, statique et utilisateur.
303 *
304 * @return array
305 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
306 *        du service.
307 */
308function owm_complement2conditions($tableau, $configuration) {
309
310        if ($tableau) {
311                // Calcul de la température ressentie et de la direction du vent (16 points), celles-ci
312                // n'étant pas fournie nativement par owm
313                include_spip('inc/rainette_convertir');
314                $tableau['temperature_ressentie'] = temperature2ressenti($tableau['temperature_reelle'], $tableau['vitesse_vent']);
315                $tableau['direction_vent'] = angle2direction($tableau['angle_vent']);
316                // On convertit aussi la visibilité en km car elle est fournie en mètres.
317                $tableau['visibilite'] = metre2kilometre($tableau['visibilite']);
318
319                // Compléter le tableau standard avec les états météorologiques calculés
320                etat2resume_owm($tableau, $configuration);
321        }
322
323        return $tableau;
324}
325
326
327/**
328 * Complète par des données spécifiques au service le tableau des conditions issu
329 * uniquement de la lecture du flux.
330 *
331 * @api
332 *
333 * @param array $tableau
334 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
335 *        par le service.
336 * @param array $configuration
337 *        Configuration complète du service, statique et utilisateur.
338 * @param int   $index_periode
339 *        Index où trouver et ranger les données. Cet index n'est pas utilisé pour les conditions
340 *
341 * @return array
342 *        Tableau standardisé des conditions météorologiques complété par les données spécifiques
343 *        du service.
344 */
345function owm_complement2previsions($tableau, $configuration, $index_periode) {
346
347        if (($tableau) and ($index_periode > -1)) {
348                // Vérifier les précipitations. Pour les prévisions, OWM renvoie le champ rain uniquement si il est
349                // 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
350                // l'affichage.
351                if ($tableau['precipitation'] === '') {
352                        $tableau['precipitation'] = 0;
353                }
354
355                // Compléter le tableau standard avec les états météorologiques calculés
356                etat2resume_owm($tableau, $configuration);
357        }
358
359        return $tableau;
360}
361
362
363/**
364 * ---------------------------------------------------------------------------------------------
365 * Les fonctions qui suivent sont des utilitaires utilisés uniquement appelées par les fonctions
366 * de l'API.
367 * PACKAGE SPIP\RAINETTE\OWM\OUTILS
368 * ---------------------------------------------------------------------------------------------
369 */
370
371/**
372 * Calcule les états en fonction des états météorologiques natifs fournis par le service.
373 *
374 * @internal
375 *
376 * @param array $tableau
377 *        Tableau standardisé des conditions contenant uniquement les données fournies sans traitement
378 *        par le service. Le tableau est mis à jour et renvoyé à l'appelant.
379 * @param array $configuration
380 *        Configuration complète du service, statique et utilisateur.
381 *
382 * @return void
383 */
384function etat2resume_owm(&$tableau, $configuration) {
385
386        if ($tableau['code_meteo'] and $tableau['icon_meteo']) {
387                // Determination de l'indicateur jour/nuit qui permet de choisir le bon icone
388                // Pour ce service le nom du fichier icone finit par "d" pour le jour et
389                // par "n" pour la nuit.
390                $icone = $tableau['icon_meteo'];
391                if (strpos($icone, 'n') === false) {
392                        // C'est le jour
393                        $tableau['periode'] = 0;
394                } else {
395                        // C'est la nuit
396                        $tableau['periode'] = 1;
397                }
398
399                // Determination, suivant le mode choisi, du code, de l'icone et du resume qui seront affiches
400                if ($configuration['condition'] == $configuration['alias']) {
401                        // On affiche les conditions natives fournies par le service.
402                        // Celles-ci etant deja traduites dans la bonne langue on stocke le texte exact retourne par l'API
403                        $tableau['icone']['code'] = $tableau['code_meteo'];
404                        $url = _RAINETTE_OWM_URL_BASE_ICONE . '/' . $tableau['icon_meteo'] . '.png';
405                        $tableau['icone']['url'] = copie_locale($url);
406                        $tableau['resume'] = ucfirst($tableau['desc_meteo']);
407                } else {
408                        // On affiche les conditions traduites dans le systeme weather.com
409                        // Pour le resume on stocke le code et non la traduction pour eviter de generer
410                        // un cache par langue comme pour le mode natif. La traduction est faite via les fichiers de langue
411                        $meteo = meteo_owm2weather($tableau['code_meteo'], $tableau['periode']);
412                        $tableau['icone'] = $meteo;
413                        $tableau['resume'] = $meteo;
414                }
415        }
416}
417
418
419// TODO : mettre au point le transcodage omw vers weather
420function meteo_owm2weather($meteo, $periode = 0) {
421        static $owm2weather = array(
422                'chanceflurries'  => array(41, 46),
423                'chancerain'      => array(39, 45),
424                'chancesleet'     => array(39, 45),
425                'chancesnow'      => array(41, 46),
426                'chancetstorms'   => array(38, 47),
427                'clear'           => array(32, 31),
428                'cloudy'          => array(26, 26),
429                'flurries'        => array(15, 15),
430                'fog'             => array(20, 20),
431                'hazy'            => array(21, 21),
432                'mostlycloudy'    => array(28, 27),
433                'mostlysunny'     => array(34, 33),
434                'partlycloudy'    => array(30, 29),
435                'partlysunny'     => array(28, 27),
436                'sleet'           => array(5, 5),
437                'rain'            => array(11, 11),
438                'snow'            => array(16, 16),
439                'sunny'           => array(32, 31),
440                'tstorms'         => array(4, 4),
441                'thunderstorms'   => array(4, 4),
442                'unknown'         => array(4, 4),
443                'scatteredclouds' => array(30, 29),
444                'overcast'        => array(26, 26)
445        );
446
447        $icone = 'na';
448        if (array_key_exists($meteo, $owm2weather)) {
449                $icone = strval($owm2weather[$meteo][$periode]);
450        }
451
452        return $icone;
453}
Note: See TracBrowser for help on using the repository browser.