script 'open weather'

Discussion et échanges de scripts pour la box eedomus

script 'open weather'

Messagepar flouret » 15 Jan 2026 09:54

Bonjour,
Pas moyen de faire fonctionner le script 'open weather' qui me renvoie ces messages :
"Température ressentie ACCU WEATHER en erreur: [Valeur non numérique []]. Aperçu du contenu."
"<?xml version="1.0" encoding="UTF-8"?><donnees_meteo><modes mode="" /><daily>"

Quelqu'un voit le problème ?
cordialement
Marc
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 15 Jan 2026 10:15

Bonjour Marc
flouret a écrit:Bonjour,
Pas moyen de faire fonctionner le script 'open weather' qui me renvoie ces messages :
"Température ressentie ACCU WEATHER en erreur: [Valeur non numérique []]. Aperçu du contenu."
"<?xml version="1.0" encoding="UTF-8"?><donnees_meteo><modes mode="" /><daily>"

Quelqu'un voit le problème ?
cordialement
Marc

Peux-tu renvoyer le contenu du XPATH et l'ensemble de la réponse obtenue depuis la fenêtre de test
<?xml version="1.0" encoding="UTF-8"?><donnees_meteo><modes mode="" /><daily>...</donnees_meteo>" :)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 15 Jan 2026 10:22

Voici une copie d'écran

Capture d’écran 2026-01-15 102119.jpg
Capture d’écran 2026-01-15 102119.jpg (59.65 Kio) Consulté 1085 fois
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 15 Jan 2026 11:27

Bonjour Marc
Effectivement, le code XML est tronqué : il n'est pas valide.
Chez moi, la réponse XML est valide, mais les valeurs sont fausses (-9999) car je n'ai pas repris d'inscription lorsqu'Openweather a changé de politique.
Peux-tu montrer le début du script le commentaire de début et quelques dizaines de lignes, pour que j'identifie la version? :)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 15 Jan 2026 12:13

voila

Capture d’écran 2026-01-15 121232.jpg
Capture d’écran 2026-01-15 121232.jpg (327.54 Kio) Consulté 1066 fois
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 15 Jan 2026 19:48

Bonsoir Marc
Désolé pour le retard.
J'ai une version plus ancienne que je ne fais plus tourner en fait.
Je pourrai essayer ta version demain, mais mon compte n'est plus valable, si le plantage est au début, je le verrai peut-être, mais ce n'est pas sur.
En attendant, tu peux essayer en mode test de rajouter &debug=1 à la ligne de commande et observer la réponse : peut-être y aura-t-il un indice sur la position de l'erreur.
http://localhost/script/?exec=openweath ... ..&debug=1
:)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 15 Jan 2026 21:33

Ok merci, je vais essayer le debug.
Par contre, obtenir une clef sur open weather est très facile
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar flouret » 15 Jan 2026 21:45

ça me renvoie ça à la fin.
J'avoue que cela ne me parle pas trop

Capture d’écran 2026-01-15 214316.jpg
Capture d’écran 2026-01-15 214316.jpg (79.29 Kio) Consulté 1018 fois
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar flouret » 15 Jan 2026 21:46

Du coup tu utilises quoi comme script de previsions météo ?
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 16 Jan 2026 09:55

Bonjour
Il me faudrait l'ensemble de la fenêtre et pas seulement la fin qui est normale.
flouret a écrit:Du coup tu utilises quoi comme script de previsions météo ?

En fait je n'en n'utilise pas ;) ;)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 16 Jan 2026 11:16

Bonjour,
J'ai essayé d'autres script météo (weather stack / apixu) et en fait j'ai le même souci.
Le problème vient de chez moi ou de chez eedomus il me semble.
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 16 Jan 2026 13:33

Bonjour
flouret a écrit:Bonjour,
J'ai essayé d'autres script météo (weather stack / apixu) et en fait j'ai le même souci.
Le problème vient de chez moi ou de chez eedomus il me semble.

As-tu essayé de recharger le script?
Il me faudrait le début de la réponse en mode debug.
J'ai rechargé la dernière version du script.
Ca tourne, mais ne renvoie pas les bonnes valeurs car je n'ai pas d'abonnement.
Erreur :
<code retour_API_meteo="401" message_API_meteo="Invalid API key. Please see https://openweathermap.org/faq#error401 for more info." retour_API_qualite="200" message_API_qualite="OK" />
en mode test , j'ai (après suppression de quelques lignes)
Code : Tout sélectionner
<?xml version="1.0" encoding="UTF-8"?>
<donnees_meteo>
<modes mode="" />
<commune city_GPS="Saint-Leu-la-Forêt : Île-de-France (49.013°, 2.243°)" country="FR" state="Île-de-France" zip="95320" lat="_" lon="_" timezone="#Erreur" timezone_offset="-9999" />
<code retour_API_meteo="401" message_API_meteo="Invalid API key. Please see https://openweathermap.org/faq#error401 for more info." retour_API_qualite="200" message_API_qualite="OK" />
<current num="0" nom="now" dt="-9999" date_loc_str="#Erreur" heure_loc_str="#Erreur" jour_loc_semaine="-9999" jour_loc_fr="#Erreur" sunrise="-9999" sunset="-9999" sunrise_hloc="-9999" sunset_hloc="-9999" moonrise="-9999" moonset="-9999" moonrise_hloc="-9999" moonset_hloc="-9999" moon_phase="-9999" night="1" temperature="-9999" temp_morn="-9999" temp_day="-9999" temp_eve="-9999" temp_night="-9999" temp_min="-9999" temp_max="-9999" feels_like="-9999" temp_like_morn="-9999" temp_like_day="-9999" temp_like_eve="-9999" temp_like_night="-9999" pressure="-9999" humidity="-9999" dew_point="-9999" wind_speed="-9999" wind_gust="-9999" wind_deg="-9999" clouds="-9999" uvi="-9999" visibility="-9999" pop="-9999" rain="_" snow="_" weather_id="-9999" weather_main="#Erreur" weather_desc="#Erreur" />
<precipitation averse_hauteur="-9999" averse_duree="60" averse_debut_hloc="10:48" averse_fin_hloc="11:48" />
<dju dju_prev="_" dju_tmin="100" dju_tmax="-100" />
<daily>
<day num="0" nom="auj" dt="-9999" date_loc_str="#Erreur" heure_loc_str="#Erreur" jour_loc_semaine="-9999" jour_loc_fr="#Erreur" sunrise="-9999" sunset="-9999" sunrise_hloc="-9999" sunset_hloc="-9999" moonrise="-9999" moonset="-9999" moonrise_hloc="-9999" moonset_hloc="-9999" moon_phase="-9999" night="1" temperature="-9999" temp_morn="-9999" temp_day="-9999" temp_eve="-9999" temp_night="-9999" temp_min="-9999" temp_max="-9999" feels_like="Array" temp_like_morn="-9999" temp_like_day="-9999" temp_like_eve="-9999" temp_like_night="-9999" pressure="-9999" humidity="-9999" dew_point="-9999" wind_speed="-9999" wind_gust="-9999" wind_deg="-9999" clouds="-9999" uvi="-9999" visibility="-9999" pop="-9999" rain="_" snow="_" weather_id="-9999" weather_main="#Erreur" weather_desc="#Erreur" />
.....
<day num="7" nom="ven" dt="-9999" date_loc_str="#Erreur" heure_loc_str="#Erreur" jour_loc_semaine="-9999" jour_loc_fr="#Erreur" sunrise="-9999" sunset="-9999" sunrise_hloc="-9999" sunset_hloc="-9999" moonrise="-9999" moonset="-9999" moonrise_hloc="-9999" moonset_hloc="-9999" moon_phase="-9999" night="1" temperature="-9999" temp_morn="-9999" temp_day="-9999" temp_eve="-9999" temp_night="-9999" temp_min="-9999" temp_max="-9999" feels_like="Array" temp_like_morn="-9999" temp_like_day="-9999" temp_like_eve="-9999" temp_like_night="-9999" pressure="-9999" humidity="-9999" dew_point="-9999" wind_speed="-9999" wind_gust="-9999" wind_deg="-9999" clouds="-9999" uvi="-9999" visibility="-9999" pop="-9999" rain="_" snow="_" weather_id="-9999" weather_main="#Erreur" weather_desc="#Erreur" />
</daily>
<hourly>
<hour num="0" nom="now" dt="-9999" date_loc_str="#Erreur" heure_loc_str="#Erreur" jour_loc_semaine="-9999" jour_loc_fr="#Erreur" sunrise="-9999" sunset="-9999" sunrise_hloc="-9999" sunset_hloc="-9999" moonrise="-9999" moonset="-9999" moonrise_hloc="-9999" moonset_hloc="-9999" moon_phase="-9999" night="1" temperature="-9999" temp_morn="_" temp_day="_" temp_eve="_" temp_night="_" temp_min="_" temp_max="_" feels_like="-9999" temp_like_morn="_" temp_like_day="_" temp_like_eve="_" temp_like_night="_" pressure="-9999" humidity="-9999" dew_point="-9999" wind_speed="-9999" wind_gust="-9999" wind_deg="-9999" clouds="-9999" uvi="-9999" visibility="-9999" pop="-9999" rain="_" snow="_" weather_id="-9999" weather_main="#Erreur" weather_desc="#Erreur" />
.....
<hour num="47" nom="*0" dt="-9999" date_loc_str="#Erreur" heure_loc_str="#Erreur" jour_loc_semaine="-9999" jour_loc_fr="#Erreur" sunrise="-9999" sunset="-9999" sunrise_hloc="-9999" sunset_hloc="-9999" moonrise="-9999" moonset="-9999" moonrise_hloc="-9999" moonset_hloc="-9999" moon_phase="-9999" night="1" temperature="-9999" temp_morn="_" temp_day="_" temp_eve="_" temp_night="_" temp_min="_" temp_max="_" feels_like="-9999" temp_like_morn="_" temp_like_day="_" temp_like_eve="_" temp_like_night="_" pressure="-9999" humidity="-9999" dew_point="-9999" wind_speed="-9999" wind_gust="-9999" wind_deg="-9999" clouds="-9999" uvi="-9999" visibility="-9999" pop="-9999" rain="_" snow="_" weather_id="-9999" weather_main="#Erreur" weather_desc="#Erreur" />
</hourly>
<donnees_qualite dt="1768560499" air_aqi="2" air_no="0.07" air_no2="3" air_o3="64.11" air_so2="0.25" air_co="156.05" air_pm2_5="1.11" air_pm10="2" air_nh3="0.18" />
</donnees_meteo>

:)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 16 Jan 2026 15:27

J'ai supprimé les périphériques, mais le script reste dans ma liste je crois. Je vais supprimer le script et recommencer.

Voici le résultat en mode debug :

device: sensor
mode - array(9) {
["com"]=>
int(1)
["err"]=>
int(1)
["cur"]=>
int(1)
["pre"]=>
int(1)
["alr"]=>
int(1)
["dju"]=>
int(1)
["qua"]=>
int(1)
["day"]=>
int(1)
["hor"]=>
int(1)
}
days - array(8) {
[0]=>
int(1)
[1]=>
int(1)
[2]=>
int(1)
[3]=>
int(1)
[4]=>
int(1)
[5]=>
int(1)
[6]=>
int(1)
[7]=>
int(1)
}
old_data[days] - array(0) {
}
hours - array(48) {
[0]=>
int(1)
[1]=>
int(1)
[2]=>
int(1)
[3]=>
int(1)
[4]=>
int(1)
[5]=>
int(1)
[6]=>
int(1)
[7]=>
int(1)
[8]=>
int(1)
[9]=>
int(1)
[10]=>
int(1)
[11]=>
int(1)
[12]=>
int(1)
[13]=>
int(1)
[14]=>
int(1)
[15]=>
int(1)
[16]=>
int(1)
[17]=>
int(1)
[18]=>
int(1)
[19]=>
int(1)
[20]=>
int(1)
[21]=>
int(1)
[22]=>
int(1)
[23]=>
int(1)
[24]=>
int(1)
[25]=>
int(1)
[26]=>
int(1)
[27]=>
int(1)
[28]=>
int(1)
[29]=>
int(1)
[30]=>
int(1)
[31]=>
int(1)
[32]=>
int(1)
[33]=>
int(1)
[34]=>
int(1)
[35]=>
int(1)
[36]=>
int(1)
[37]=>
int(1)
[38]=>
int(1)
[39]=>
int(1)
[40]=>
int(1)
[41]=>
int(1)
[42]=>
int(1)
[43]=>
int(1)
[44]=>
int(1)
[45]=>
int(1)
[46]=>
int(1)
[47]=>
int(1)
}
old_data[hours] - array(0) {
}
xml[days] - string(0) ""
xml[hours] - string(0) ""
<br />
<b>Warning</b>: Cannot modify header information - headers already sent by (output started at /mnt/flash/puch/www/script/user/21670/openweather.php:434) in <b>/mnt/flash/puch/www/script/script_include.php</b> on line <b>74</b><br />
<?xml version="1.0" encoding="UTF-8"?>
<donnees_meteo>
<modes mode="" />
<daily>
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 16 Jan 2026 16:06

En fait, il faudrait voir ce que dit le "Master", les autres ne font que relire la mémoire.
Le master a comme chaine de commande
http://localhost/script/?exec=openweath ... id=2818449
Normalement, c'est celui qui s'appelle "Ville station Meteo"
Dans mon cas en mode test il répond "1", ce qui est en fait le signe d'une réponse erronée de la box (instruction incorrecte dans le script)
En mode debug, j'obtiens
Code : Tout sélectionner
device: master
Reprise ancienne localisation
url_meteo= http://api.openweathermap.org/data/3.0/onecall?lat=49.0133&lon=2.2429&units=metric&lang=FR&mode=Json&appid=....
reponse : {"cod":401, "message": "Please note that using One Call 3.0 requires a separate subscription to the One Call by Call plan. Learn more here https://openweathermap.org/price. If you have a valid subscription to the One Call by Call plan, but still receive this error, then please see https://openweathermap.org/faq#error401 for more info."}
Commune : <commune city_GPS="Saint-Leu-la-Forêt : Île-de-France (49.013�, 2.243�)" country="FR" state="Île-de-France" zip="95320" lat="_" lon="_" timezone="#Erreur" timezone_offset="-9999" />


Normal, puisque je n'ai pas de compte, mais la sortie devrait être mieux traitée.

Si je force la relocalisation, test avec &debug=1&reloc=1
J'obtiens bien ce qu'il faut, mais ça bloque toujours à l'appel de OneCall : Normal

Code : Tout sélectionner
device: master
array(1) {
  [0]=>
  string(5) "95320"
}
nbr_elements = 1 Type commune : zip
FR
array(7) {
  ["zip"]=>
  string(5) "95320"
  ["name"]=>
  string(0) ""
  ["lat"]=>
  int(199)
  ["lon"]=>
  int(199)
  ["state"]=>
  string(0) ""
  ["country"]=>
  string(2) "FR"
  ["valid"]=>
  bool(false)
}
url_GPS : http://api-adresse.data.gouv.fr/search/?q=95320&limit=1
reponse : {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[2.242938,49.013301]},"properties":{"label":"Saint-Leu-la-Forêt","score":0.8572036363636363,"id":"95563","banId":"f635bb90-abcd-4d22-b5a1-3ef35ae8f1cc","type":"municipality","name":"Saint-Leu-la-Forêt","postcode":"95320","citycode":"95563","x":644619.45,"y":6879531.4,"population":16047,"city":"Saint-Leu-la-Forêt","context":"95, Val-d'Oise, Île-de-France","importance":0.42924,"municipality":"Saint-Leu-la-Forêt","_type":"address"}}],"query":"95320"}
array(7) {
  ["zip"]=>
  string(5) "95320"
  ["name"]=>
  string(18) "Saint-Leu-la-Forêt"
  ["lat"]=>
  string(7) "49.0133"
  ["lon"]=>
  string(6) "2.2429"
  ["state"]=>
  string(13) "Île-de-France"
  ["country"]=>
  string(2) "FR"
  ["valid"]=>
  bool(true)
}
Calcul nouvelle localisation
url_meteo= http://api.openweathermap.org/data/3.0/onecall?lat=49.0133&lon=2.2429&units=metric&lang=FR&mode=Json&appid=......
reponse : {"cod":401, "message": "Please note that using One Call 3.0 requires a separate subscription to the One Call by Call plan. Learn more here https://openweathermap.org/price. If you have a valid subscription to the One Call by Call plan, but still receive this error, then please see https://openweathermap.org/faq#error401 for more info."}
Commune : <commune city_GPS="Saint-Leu-la-Forêt : Île-de-France (49.013�, 2.243�)" country="FR" state="Île-de-France" zip="95320" lat="_" lon="_" timezone="#Erreur" timezone_offset="-9999" />

:)
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 16 Jan 2026 17:19

Le master me renvoie 1 aussi
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar flouret » 16 Jan 2026 17:22

avec debug et reloc :

device: master
array(1) {
[0]=>
string(5) "Paris"
}
nbr_elements = 1 Type commune : name
FR
array(7) {
["zip"]=>
int(0)
["name"]=>
string(5) "Paris"
["lat"]=>
int(199)
["lon"]=>
int(199)
["state"]=>
string(0) ""
["country"]=>
string(2) "FR"
["valid"]=>
bool(false)
}
url_GPS : http://api-adresse.data.gouv.fr/search/?q=Paris&limit=1
reponse : {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[2.347,48.859]},"properties":{"label":"Paris","score":0.9702972727272726,"id":"75056","type":"municipality","name":"Paris","postcode":"75001","citycode":"75056","x":652089.7,"y":6862305.26,"population":2113705,"city":"Paris","context":"75, Paris, ÃŽle-de-France","importance":0.67327,"municipality":"Paris","_type":"address"}}],"query":"Paris"}
array(7) {
["zip"]=>
string(5) "75001"
["name"]=>
string(5) "Paris"
["lat"]=>
string(7) "48.8590"
["lon"]=>
string(6) "2.3470"
["state"]=>
string(13) "Île-de-France"
["country"]=>
string(2) "FR"
["valid"]=>
bool(true)
}
Calcul nouvelle localisation
url_meteo= http://api.openweathermap.org/data/3.0/ ... 9145918221
reponse : {"cod":401, "message": "Please note that using One Call 3.0 requires a separate subscription to the One Call by Call plan. Learn more here https://openweathermap.org/price. If you have a valid subscription to the One Call by Call plan, but still receive this error, then please see https://openweathermap.org/faq#error401 for more info."}
Commune : <commune city_GPS="Paris : Île-de-France (48.859°, 2.347°)" country="FR" state="Île-de-France" zip="75001" lat="_" lon="_" timezone="#Erreur" timezone_offset="-9999" />
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar flouret » 16 Jan 2026 22:02

Les choses ont un peu évolué.
J'ai pris un abonnement 1000 appels par jour puis 0.0014e par appel.
la réponse en mode debug est différente. il renvoie les infos il me semble.

device: master
array(1) {
[0]=>
string(5) "Paris"
}
nbr_elements = 1 Type commune : name
FR
array(7) {
["zip"]=>
int(0)
["name"]=>
string(5) "Paris"
["lat"]=>
int(199)
["lon"]=>
int(199)
["state"]=>
string(0) ""
["country"]=>
string(2) "FR"
["valid"]=>
bool(false)
}
url_GPS : http://api-adresse.data.gouv.fr/search/?q=Paris&limit=1
reponse : {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[2.347,48.859]},"properties":{"label":"Paris","score":0.9702972727272726,"id":"75056","type":"municipality","name":"Paris","postcode":"75001","citycode":"75056","x":652089.7,"y":6862305.26,"population":2113705,"city":"Paris","context":"75, Paris, ÃŽle-de-France","importance":0.67327,"municipality":"Paris","_type":"address"}}],"query":"Paris"}
array(7) {
["zip"]=>
string(5) "75001"
["name"]=>
string(5) "Paris"
["lat"]=>
string(7) "48.8590"
["lon"]=>
string(6) "2.3470"
["state"]=>
string(13) "Île-de-France"
["country"]=>
string(2) "FR"
["valid"]=>
bool(true)
}
Calcul nouvelle localisation
url_meteo= http://api.openweathermap.org/data/3.0/ ... 9145918221
reponse : {"lat":48.859,"lon":2.347,"timezone":"Europe/Paris","timezone_offset":3600,"current":{"dt":1768596636,"sunrise":1768549085,"sunset":1768580526,"temp":9.36,"feels_like":7.69,"pressure":1012,"humidity":93,"dew_point":8.29,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":3.09,"wind_deg":150,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}]},"minutely":[{"dt":1768596660,"precipitation":0},{"dt":1768596720,"precipitation":0},{"dt":1768596780,"precipitation":0},{"dt":1768596840,"precipitation":0},{"dt":1768596900,"precipitation":0},{"dt":1768596960,"precipitation":0},{"dt":1768597020,"precipitation":0},{"dt":1768597080,"precipitation":0},{"dt":1768597140,"precipitation":0},{"dt":1768597200,"precipitation":0},{"dt":1768597260,"precipitation":0},{"dt":1768597320,"precipitation":0},{"dt":1768597380,"precipitation":0},{"dt":1768597440,"precipitation":0},{"dt":1768597500,"precipitation":0},{"dt":1768597560,"precipitation":0},{"dt":1768597620,"precipitation":0},{"dt":1768597680,"precipitation":0},{"dt":1768597740,"precipitation":0},{"dt":1768597800,"precipitation":0},{"dt":1768597860,"precipitation":0},{"dt":1768597920,"precipitation":0},{"dt":1768597980,"precipitation":0},{"dt":1768598040,"precipitation":0},{"dt":1768598100,"precipitation":0},{"dt":1768598160,"precipitation":0},{"dt":1768598220,"precipitation":0},{"dt":1768598280,"precipitation":0},{"dt":1768598340,"precipitation":0},{"dt":1768598400,"precipitation":0},{"dt":1768598460,"precipitation":0},{"dt":1768598520,"precipitation":0},{"dt":1768598580,"precipitation":0},{"dt":1768598640,"precipitation":0},{"dt":1768598700,"precipitation":0},{"dt":1768598760,"precipitation":0},{"dt":1768598820,"precipitation":0},{"dt":1768598880,"precipitation":0},{"dt":1768598940,"precipitation":0},{"dt":1768599000,"precipitation":0},{"dt":1768599060,"precipitation":0},{"dt":1768599120,"precipitation":0},{"dt":1768599180,"precipitation":0},{"dt":1768599240,"precipitation":0},{"dt":1768599300,"precipitation":0},{"dt":1768599360,"precipitation":0},{"dt":1768599420,"precipitation":0},{"dt":1768599480,"precipitation":0},{"dt":1768599540,"precipitation":0},{"dt":1768599600,"precipitation":0},{"dt":1768599660,"precipitation":0},{"dt":1768599720,"precipitation":0},{"dt":1768599780,"precipitation":0},{"dt":1768599840,"precipitation":0},{"dt":1768599900,"precipitation":0},{"dt":1768599960,"precipitation":0},{"dt":1768600020,"precipitation":0},{"dt":1768600080,"precipitation":0},{"dt":1768600140,"precipitation":0},{"dt":1768600200,"precipitation":0}],"hourly":[{"dt":1768593600,"temp":9.26,"feels_like":8.26,"pressure":1012,"humidity":93,"dew_point":8.19,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.09,"wind_deg":129,"wind_gust":6.55,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768597200,"temp":9.36,"feels_like":8.24,"pressure":1012,"humidity":93,"dew_point":8.29,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.26,"wind_deg":135,"wind_gust":6.84,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768600800,"temp":9.31,"feels_like":8.03,"pressure":1012,"humidity":92,"dew_point":8.08,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.47,"wind_deg":148,"wind_gust":7.94,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768604400,"temp":9.2,"feels_like":8.68,"pressure":1012,"humidity":91,"dew_point":7.81,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.55,"wind_deg":181,"wind_gust":5.73,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.46},{"dt":1768608000,"temp":8.99,"feels_like":8.99,"pressure":1013,"humidity":92,"dew_point":7.76,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":0.98,"wind_deg":158,"wind_gust":3.21,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10n"}],"pop":0.72,"rain":{"1h":0.37}},{"dt":1768611600,"temp":8.87,"feels_like":8.87,"pressure":1013,"humidity":92,"dew_point":7.64,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.15,"wind_deg":157,"wind_gust":3.98,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10n"}],"pop":0.69,"rain":{"1h":0.19}},{"dt":1768615200,"temp":8.52,"feels_like":7.88,"pressure":1013,"humidity":93,"dew_point":7.49,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.57,"wind_deg":155,"wind_gust":4.71,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.33},{"dt":1768618800,"temp":8.15,"feels_like":7.32,"pressure":1013,"humidity":96,"dew_point":7.3,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.7,"wind_deg":169,"wind_gust":4.73,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.14},{"dt":1768622400,"temp":7.71,"feels_like":7.03,"pressure":1013,"humidity":96,"dew_point":7.13,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.51,"wind_deg":160,"wind_gust":3.19,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.03},{"dt":1768626000,"temp":7.35,"feels_like":6.51,"pressure":1014,"humidity":96,"dew_point":6.96,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.6,"wind_deg":158,"wind_gust":4.14,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768629600,"temp":6.55,"feels_like":5.44,"pressure":1014,"humidity":97,"dew_point":6.91,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.74,"wind_deg":137,"wind_gust":4.77,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768633200,"temp":6.46,"feels_like":5.65,"pressure":1014,"humidity":96,"dew_point":6.79,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.47,"wind_deg":136,"wind_gust":2.64,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768636800,"temp":6.97,"feels_like":6.97,"pressure":1015,"humidity":95,"dew_point":6.78,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.22,"wind_deg":134,"wind_gust":2.28,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768640400,"temp":7.48,"feels_like":6.73,"pressure":1016,"humidity":94,"dew_point":6.75,"uvi":0.21,"clouds":100,"visibility":10000,"wind_speed":1.54,"wind_deg":137,"wind_gust":4.67,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768644000,"temp":8.39,"feels_like":8.39,"pressure":1016,"humidity":89,"dew_point":6.75,"uvi":0.43,"clouds":100,"visibility":10000,"wind_speed":1.2,"wind_deg":142,"wind_gust":3.1,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768647600,"temp":9.49,"feels_like":9.09,"pressure":1016,"humidity":87,"dew_point":6.89,"uvi":0.5,"clouds":100,"visibility":10000,"wind_speed":1.48,"wind_deg":124,"wind_gust":2.82,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768651200,"temp":9.96,"feels_like":9.45,"pressure":1016,"humidity":83,"dew_point":7.03,"uvi":0.69,"clouds":100,"visibility":10000,"wind_speed":1.65,"wind_deg":123,"wind_gust":3.12,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768654800,"temp":9.47,"feels_like":9.22,"pressure":1016,"humidity":87,"dew_point":7.23,"uvi":0.56,"clouds":100,"visibility":10000,"wind_speed":1.34,"wind_deg":101,"wind_gust":3.9,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768658400,"temp":9.28,"feels_like":8.94,"pressure":1016,"humidity":89,"dew_point":7.4,"uvi":0.09,"clouds":100,"visibility":10000,"wind_speed":1.4,"wind_deg":78,"wind_gust":4.32,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768662000,"temp":9.74,"feels_like":9,"pressure":1016,"humidity":87,"dew_point":7.53,"uvi":0.04,"clouds":100,"visibility":10000,"wind_speed":1.87,"wind_deg":75,"wind_gust":5.2,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768665600,"temp":9.66,"feels_like":8.82,"pressure":1015,"humidity":88,"dew_point":7.58,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.97,"wind_deg":74,"wind_gust":5.67,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768669200,"temp":9.51,"feels_like":8.71,"pressure":1016,"humidity":90,"dew_point":7.62,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":1.9,"wind_deg":76,"wind_gust":5.97,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768672800,"temp":9.43,"feels_like":8.2,"pressure":1016,"humidity":90,"dew_point":7.73,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.43,"wind_deg":82,"wind_gust":8.33,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768676400,"temp":9.08,"feels_like":7.72,"pressure":1017,"humidity":91,"dew_point":7.45,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.52,"wind_deg":98,"wind_gust":8.04,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768680000,"temp":9.1,"feels_like":7.73,"pressure":1017,"humidity":89,"dew_point":7.13,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.54,"wind_deg":106,"wind_gust":8.91,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768683600,"temp":9.4,"feels_like":8.04,"pressure":1017,"humidity":85,"dew_point":6.84,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.61,"wind_deg":101,"wind_gust":8.41,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768687200,"temp":9.62,"feels_like":8.16,"pressure":1017,"humidity":82,"dew_point":6.53,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.82,"wind_deg":106,"wind_gust":8.75,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768690800,"temp":9.44,"feels_like":8.27,"pressure":1017,"humidity":84,"dew_point":6.6,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.35,"wind_deg":91,"wind_gust":6.47,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768694400,"temp":9.55,"feels_like":8.04,"pressure":1017,"humidity":84,"dew_point":6.79,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.88,"wind_deg":101,"wind_gust":9.43,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768698000,"temp":9.31,"feels_like":8.09,"pressure":1017,"humidity":86,"dew_point":6.8,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.38,"wind_deg":106,"wind_gust":7.78,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10n"}],"pop":0.66,"rain":{"1h":0.14}},{"dt":1768701600,"temp":9.24,"feels_like":7.64,"pressure":1017,"humidity":79,"dew_point":5.6,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.93,"wind_deg":83,"wind_gust":9.03,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.45},{"dt":1768705200,"temp":8.94,"feels_like":7.42,"pressure":1017,"humidity":69,"dew_point":3.51,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.72,"wind_deg":98,"wind_gust":9.41,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0.03},{"dt":1768708800,"temp":8.59,"feels_like":7.14,"pressure":1017,"humidity":68,"dew_point":2.85,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.52,"wind_deg":98,"wind_gust":9.08,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768712400,"temp":8.18,"feels_like":6.77,"pressure":1017,"humidity":68,"dew_point":2.53,"uvi":0,"clouds":100,"visibility":10000,"wind_speed":2.36,"wind_deg":93,"wind_gust":9.06,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768716000,"temp":7.6,"feels_like":6,"pressure":1018,"humidity":69,"dew_point":2.2,"uvi":0,"clouds":99,"visibility":10000,"wind_speed":2.47,"wind_deg":101,"wind_gust":8.66,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768719600,"temp":7.44,"feels_like":5.53,"pressure":1018,"humidity":68,"dew_point":1.81,"uvi":0,"clouds":99,"visibility":10000,"wind_speed":2.86,"wind_deg":98,"wind_gust":9.77,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04n"}],"pop":0},{"dt":1768723200,"temp":7.21,"feels_like":5.61,"pressure":1018,"humidity":67,"dew_point":1.44,"uvi":0,"clouds":99,"visibility":10000,"wind_speed":2.38,"wind_deg":91,"wind_gust":8.75,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768726800,"temp":7.42,"feels_like":5.84,"pressure":1018,"humidity":65,"dew_point":1.18,"uvi":0.21,"clouds":99,"visibility":10000,"wind_speed":2.41,"wind_deg":82,"wind_gust":8.53,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768730400,"temp":8.03,"feels_like":6.24,"pressure":1018,"humidity":61,"dew_point":0.83,"uvi":0.4,"clouds":100,"visibility":10000,"wind_speed":2.86,"wind_deg":87,"wind_gust":6.75,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768734000,"temp":8.92,"feels_like":7.31,"pressure":1018,"humidity":57,"dew_point":0.67,"uvi":0.64,"clouds":99,"visibility":10000,"wind_speed":2.85,"wind_deg":92,"wind_gust":5.52,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768737600,"temp":9.72,"feels_like":8.27,"pressure":1018,"humidity":54,"dew_point":0.65,"uvi":0.72,"clouds":95,"visibility":10000,"wind_speed":2.84,"wind_deg":98,"wind_gust":5.19,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"pop":0},{"dt":1768741200,"temp":10.28,"feels_like":8.72,"pressure":1017,"humidity":52,"dew_point":0.72,"uvi":0.63,"clouds":69,"visibility":10000,"wind_speed":2.7,"wind_deg":96,"wind_gust":4.85,"weather":[{"id":803,"main":"Clouds","description":"nuageux","icon":"04d"}],"pop":0},{"dt":1768744800,"temp":10.51,"feels_like":8.97,"pressure":1017,"humidity":52,"dew_point":0.99,"uvi":0.4,"clouds":61,"visibility":10000,"wind_speed":2.61,"wind_deg":119,"wind_gust":4.2,"weather":[{"id":803,"main":"Clouds","description":"nuageux","icon":"04d"}],"pop":0},{"dt":1768748400,"temp":10.23,"feels_like":8.74,"pressure":1017,"humidity":55,"dew_point":1.37,"uvi":0.18,"clouds":50,"visibility":10000,"wind_speed":2.3,"wind_deg":125,"wind_gust":3.59,"weather":[{"id":802,"main":"Clouds","description":"partiellement nuageux","icon":"03d"}],"pop":0},{"dt":1768752000,"temp":9.49,"feels_like":9,"pressure":1016,"humidity":59,"dew_point":1.77,"uvi":0,"clouds":53,"visibility":10000,"wind_speed":1.56,"wind_deg":86,"wind_gust":3.21,"weather":[{"id":803,"main":"Clouds","description":"nuageux","icon":"04d"}],"pop":0},{"dt":1768755600,"temp":8.64,"feels_like":7.72,"pressure":1017,"humidity":64,"dew_point":2.18,"uvi":0,"clouds":45,"visibility":10000,"wind_speed":1.88,"wind_deg":79,"wind_gust":4.29,"weather":[{"id":802,"main":"Clouds","description":"partiellement nuageux","icon":"03n"}],"pop":0},{"dt":1768759200,"temp":7.95,"feels_like":6.84,"pressure":1017,"humidity":69,"dew_point":2.56,"uvi":0,"clouds":42,"visibility":10000,"wind_speed":1.96,"wind_deg":82,"wind_gust":4.9,"weather":[{"id":802,"main":"Clouds","description":"partiellement nuageux","icon":"03n"}],"pop":0},{"dt":1768762800,"temp":7.38,"feels_like":6.15,"pressure":1017,"humidity":73,"dew_point":2.75,"uvi":0,"clouds":57,"visibility":10000,"wind_speed":1.99,"wind_deg":89,"wind_gust":5.28,"weather":[{"id":803,"main":"Clouds","description":"nuageux","icon":"04n"}],"pop":0}],"daily":[{"dt":1768564800,"sunrise":1768549085,"sunset":1768580526,"moonrise":1768544940,"moonset":1768570680,"moon_phase":0.93,"summary":"There will be rain until morning, then partly cloudy","temp":{"day":10.58,"min":7.97,"max":10.99,"night":9.31,"eve":9.23,"morn":8},"feels_like":{"day":9.76,"night":8.03,"eve":8.66,"morn":5.94},"pressure":1012,"humidity":79,"dew_point":5.82,"wind_speed":7.29,"wind_deg":211,"wind_gust":16.18,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10d"}],"clouds":100,"pop":0.61,"rain":0.42,"uvi":0.67},{"dt":1768651200,"sunrise":1768635439,"sunset":1768667012,"moonrise":1768634100,"moonset":1768660800,"moon_phase":0.96,"summary":"Expect a day of partly cloudy with rain","temp":{"day":9.96,"min":6.46,"max":9.96,"night":9.62,"eve":9.43,"morn":6.55},"feels_like":{"day":9.45,"night":8.16,"eve":8.2,"morn":5.44},"pressure":1016,"humidity":83,"dew_point":7.03,"wind_speed":2.82,"wind_deg":106,"wind_gust":8.91,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10d"}],"clouds":100,"pop":0.72,"rain":0.56,"uvi":0.69},{"dt":1768737600,"sunrise":1768721791,"sunset":1768753500,"moonrise":1768722720,"moonset":1768751460,"moon_phase":0,"summary":"Expect a day of partly cloudy with rain","temp":{"day":9.72,"min":6.23,"max":10.51,"night":6.23,"eve":7.95,"morn":7.6},"feels_like":{"day":8.27,"night":6.23,"eve":6.84,"morn":6},"pressure":1018,"humidity":54,"dew_point":0.65,"wind_speed":2.93,"wind_deg":83,"wind_gust":9.77,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10d"}],"clouds":95,"pop":0.66,"rain":0.14,"uvi":0.72},{"dt":1768824000,"sunrise":1768808140,"sunset":1768839990,"moonrise":1768810740,"moonset":1768842300,"moon_phase":0.02,"summary":"There will be partly cloudy today","temp":{"day":10.63,"min":5.69,"max":11.97,"night":8.81,"eve":9.85,"morn":5.93},"feels_like":{"day":9.6,"night":8.09,"eve":9.51,"morn":4.76},"pressure":1017,"humidity":71,"dew_point":5.43,"wind_speed":2.03,"wind_deg":150,"wind_gust":4.62,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"clouds":90,"pop":0,"uvi":0.76},{"dt":1768910400,"sunrise":1768894486,"sunset":1768926480,"moonrise":1768898400,"moonset":1768933320,"moon_phase":0.05,"summary":"You can expect partly cloudy in the morning, with clearing in the afternoon","temp":{"day":9.41,"min":6.41,"max":10.38,"night":7.03,"eve":8.44,"morn":6.41},"feels_like":{"day":8.97,"night":7.03,"eve":7.85,"morn":6.41},"pressure":1017,"humidity":71,"dew_point":4.17,"wind_speed":1.52,"wind_deg":63,"wind_gust":2.56,"weather":[{"id":801,"main":"Clouds","description":"peu nuageux","icon":"02d"}],"clouds":12,"pop":0,"uvi":0.82},{"dt":1768996800,"sunrise":1768980830,"sunset":1769012972,"moonrise":1768985880,"moonset":1769024220,"moon_phase":0.09,"summary":"There will be clear sky until morning, then partly cloudy","temp":{"day":7.8,"min":4.41,"max":9.41,"night":6.81,"eve":7.45,"morn":4.41},"feels_like":{"day":6.26,"night":4.52,"eve":5.1,"morn":3.29},"pressure":1005,"humidity":65,"dew_point":1.38,"wind_speed":3.57,"wind_deg":123,"wind_gust":9.47,"weather":[{"id":801,"main":"Clouds","description":"peu nuageux","icon":"02d"}],"clouds":18,"pop":0,"uvi":0.84},{"dt":1769083200,"sunrise":1769067172,"sunset":1769099464,"moonrise":1769073120,"moonset":1769115180,"moon_phase":0.12,"summary":"Expect a day of partly cloudy with rain","temp":{"day":7.72,"min":5.94,"max":8.09,"night":6.8,"eve":6.92,"morn":6.61},"feels_like":{"day":5.47,"night":4.71,"eve":4.38,"morn":4.1},"pressure":1003,"humidity":82,"dew_point":4.51,"wind_speed":3.7,"wind_deg":146,"wind_gust":10.36,"weather":[{"id":500,"main":"Rain","description":"légère pluie","icon":"10d"}],"clouds":100,"pop":0.38,"rain":0.6,"uvi":1},{"dt":1769169600,"sunrise":1769153511,"sunset":1769185957,"moonrise":1769160420,"moonset":1769206200,"moon_phase":0.15,"summary":"There will be partly cloudy today","temp":{"day":5.64,"min":4.67,"max":6.71,"night":4.67,"eve":5.22,"morn":6.18},"feels_like":{"day":2.98,"night":2.03,"eve":2.62,"morn":3.91},"pressure":999,"humidity":78,"dew_point":1.97,"wind_speed":3.44,"wind_deg":99,"wind_gust":8.07,"weather":[{"id":804,"main":"Clouds","description":"couvert","icon":"04d"}],"clouds":100,"pop":0,"uvi":1}]}
Commune : <commune city_GPS="Paris : Île-de-France (48.859°, 2.347°)" country="FR" state="Île-de-France" zip="75001" lat="48.859" lon="2.347" timezone="Europe/Paris" timezone_offset="3600" />
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar opa95 » 17 Jan 2026 09:45

Bonjour Marc
Maintenant que tu as le bon abonnement, ça fonctionne.
Il y a deux erreurs dans le script de la dernière modification (ce n'est pas la mienne).

mettre la ligne 113 en commentaire, de toute façon elle est fausse $$xml au lieu de $xml
111
Code : Tout sélectionner
function sdk_alertsXML($tableau) {
112 global $delta_h;
113 //global $$xml; (au lieu de global $$xml;)

mettre la ligne 175 en commentaire
Code : Tout sélectionner
171 function sdk_formatTableauXML(&$tableau,$formatXML = 'default') {// Formattage XML
172  global $format;
173  global $delta_h;
174  global $jours_fr;
175  //global $xml; (au lieu de global $xml;)

Normalement ça fonctionne
Il reste encore des problèmes avec les caractères spéciaux, je verrai plus tard, lorsque j'aurais plus de temps (je n'utiliserai alors ton code qu'en cas d'absolue nécessité)
Résultat XPath :
Saint-Leu-la-Forêt : Île-de-France (49.013?, 2.243?) :)
Voici le script à jour
Code : Tout sélectionner
<?php

/*************************************************************************************************************************************
 * Script Meteo du Jour bas� sur le site OpenWeather.com pour box eedomus
 * D�veloppement par dommarion et opa95 V2.1
 *
 * voir la documentation en ligne pour plus de precisions
 *
 * Ce script permet de r�cup�rer la r�ponse JSON puis traduire en XML, la m�t�o du jour, la pr�vision et les polluants de l'air.
 * Les donn�es sont r�cup�r�es sur le site OpenWeather � partir des coordonn�es GPS (lat,lon) (3 appels api)
 *
 * La traduction des r�f�rences zip ou nom commune ou coordonn�es est faite par l'api : api-adresse.data.gouv.fr pour la France
 * ou l'api api.openweathermap.org/geo/1.0/ sinon.
 * La traduction n'est utilis�e que si l'adresse a �t� chang�e
 *
 * Un widget est d�clar� comme Master et effectue les demandes aux api (device=Master, casse indiff�rente, 6 premiers caract�res); les r�sultats sont m�moris�s
 * Tous les autres widgets ne font que relire les r�sultats m�moris�s par le widget Master (device[0..5] != Master ou absent)
 *
 * Appel Master : http://localhost/script/?exec=openweather.php&commune=[VAR1]&key=[VAR2]&country=[VAR3]&device=Master
 * Appel autres : http://localhost/script/?exec=openweather.php&key=[VAR2][&device=Sensor] ou
 * ou           : http://localhost/script/?exec=openweather.php&key=[VAR2][&device=Sensor]&country=[VAR3] (country est utilis� pour s�lectionner les blocs du XML)
 *   [VAR1] : Doit contenir la commune; Formats possibles :
 *            lat,lon (ou lat,lon,country ou lat,lon,state,country) ou zip ou (zip,country) ou commune (ou commune,country ou commune,state,country ou commune,zip,country)
 *   [VAR2] : Doit contenir la clef OpenWeather
 *   [VAR3] : Doit contenir l'�tat (pour US), le code pays (selon ISO 3166, 2 Lettres) : country ou state,country
 *            Les d�finitions de country et state de [VAR1] sont prioritaires sur celles de [VAR3]. Si [VAR3] contient un "_" Countery=FR
 *  mode de sortie short (par defaut)
 *  XPATH : infos standards //@nom_champ_valable
 *  exemples //@temperature ou//@hauteur ou //@air_no
 *     cas particuliers : previsions day ou hour
 *       r�sultats pr�visions : jour courant (J0)      //day[@jour='auj']/@temp_nuit ou //day[@num='0']/@temp_nuit
 *                              jour J0+n              //day[@num=n]/@temp_nuit (n entre 0 et 7)
 *                              jour de la semaine     //day[@jour='Lun']/temp_nuit (Dim -> Sam) si identique au jour courant, on obtient le jour de la semaine suivante
 *                              heure courante (H0)    //hour[@heure='now']/@temperature ou //hour[@num=0]/@temperature
 *                              heure H0+n             //hour[@num=n]/@temperature (n entre 0 et 47)
 *                              heure du jour          //hour[@heure=12]/@temperature (0 -> 23) heure du jour ou du lendemain ( *12 -> heure du lendemain ou du surlendemain)
 *  mode de sortie long (variables augment�es de 30%) : idem en �tant les "@".
 *  si extraction des donn�es, on peut obtenir un seul bloc day ou hour et interroger directement comme pour current : //@temperature (ou //temperature, selon le format).
 * Mode Debug avec en fin d'url &debug=1 (si &reloc = 1 recalcul de la commune), mettre &mem=no pour ne pas utiliser la sauvegarde en mode test
 * Format de sortie : &format=long : Format XML classique, les champs sont appel�s directement ex : //temperature  (environ 34ko)
 *                    &format=short : Format XML condens�, les champs sont appel�s directement ex : //@temperature (environ 25ko)
 *
 * Selection de blocs de sortie : tout : rien ou _all ; commune : _com ; current : _cou ; precipitation ; _alr : alertes ; _dju : DJU ; _day : days; _hor : hours; _qua : qualite
 *       si _day pas s�lectionn� : _nJ : jour J+n ; _'auj' : jour 0 ; _dim ... _sam : dimanche � samedi (_sam_dim : week_end)
 *       si _hor pas s�lectionn� : _nh : heure h+n ; _'now' : heure h ; _h (0 a 23) : heure h suivante ; _*h (*0 a *23) : heure h lendemain ou surlendemain
 *
 * Pour utiliser des widgets correspondants � des lieux diff�rents rajouter $mem=nom_mem dans la chaine de commande des widgets correspondants, par d�faut $mem='xml'
 *
 * Evolution des versions (voir documentation):
 *
 * 2021-03-06 (dommarion et opa95): V1.0 -> V1.4  - Version initiale et modifications avec choix nom ou code postal ou "lat,lon" pr�vision 3h et 24h et lecture API en latitude et longitude, mise en place MasterData et Sensors.
 * 2022-09-16 (opa95 et dommarion): V2.0 - Adaptation � API onecall 1.0 Lecture donn�es par MasterData (2 mins) Utilisation des donn�es par Sensors.
 *                                        - Valeurs actuelles, qualit� de l'air, pr�cipitations dans l'heure, pr�visions de 1h � 47h et de 1j � 7j, DJU du lendemain
 *                                        - Donn�es normalis�es
 * 2022-10-04 (opa95 et dommarion): V2.1 - Ajout de codes erreur lors de l'appel des API.
 * 2024-10-24 (opa95 et dommarion): V2.2 - passage � la version 3.0 de openWeather : n�cessite une r�inscription � openweather, mais le code 2.5 est valide
 *
 *************************************************************************************************************************************/

define ('DEFCOUNTRY' , 'FR');// par d�faut fr (France)
define ('DEFLANG' , 'FR');// par d�faut fr (France)
define ('DEFDEBUG',0);// par d�faut debug = 0 (pas de debug)
define ('DEFDEVICE','Sensor');// par d�faut mode Sensor
define ('DEFAFFICHE',39);// Longueur d'affichage de la commune

define ('SEPCOORD',',');//separateur latitude, longitude
define ('SEPMODE','_');//separateur modes
define ('SEPHEURE','*');//indicateur heure initiale >23
define ('SUFFH','h');//suffixe heure (maj ou min)
define ('SUFFJ','j');//suffixe jour (maj ou min)
define ('VOID' , '');// Code erreur champ texte
define ('NBDIGIT' , 4);// nombre de chiffres apr�s la virgule des coordonn�es
define ('DJUREF' , 18);// Temperature de reference DJU

define ('ERRCODE',-9999);//Code erreur
define ('ERRTXT','#Erreur');//Code erreur texte
define ('ERRCOORD',199);//Code erreur coordonn�es
define ('VALIDHTTP',200);//Code r�ponse valide
define ('BUFFERNAME','xml');// prefixe de la m�moire
define ('NOMEM','no');// pas de sauvegarde
define ('FORMATXML','short');// long <tag>valeur</tag> short <tags tag="valeur" /> (r�duit la taille de 25%)
define ('ELEMXML','_elem');// _beg ou _elem ou _end

define ('ALERTS',0);


//***************** heure locale
function sdk_hloc($elem,$deltaT = 0,$mode = 'hour') {// heure locale de la ville
  if ($elem == ERRCODE) return ERRCODE;
  else    {
    $elem += $deltaT;
    if ($mode == 'hour') return date('G',$elem).':'.date('i',$elem);
    else return date('Y',$elem).'-'.date('m',$elem).'-'.date('d',$elem).' '.date('G',$elem).':'.date('i',$elem);
  }
}// function sdk_hloc

//***************** testNum
function sdk_testNum(&$elem,$is_invalid = false,$err = ERRCODE) {// $elem inchang� ou mis � ERRCODE
  if ( ($is_invalid) || (!is_numeric($elem)) ) {$elem = $err;}
}// function sdk_testNum

//***************** testWeather codes
function sdk_testWeather(&$tableau,$is_invalid = false,$err = ERRCODE) {// $elem inchang� ou mis � ERRCODE
  if ( (!is_numeric($tableau['id'])) || ($is_invalid) ) {
      $tableau['id']          = ERRCODE;
      $tableau['main']        = ERRTXT;
      $tableau['description'] = ERRTXT;
      $tableau['icon']        = ERRTXT;
    }
}// function sdk_testWeather

//***************** alerts XML
function sdk_alertsXML($tableau) {
  global $delta_h;
  //global $$xml; //opa95
    $xml  = sdk_formatXML('values','_beg');
    $xml .= sdk_formatXML('sender',$tableau['sender_name']);
    $xml .= sdk_formatXML('evenement',$tableau['event']);
    $xml .= sdk_formatXML('alert_debut',$tableau['start']);
    $xml .= sdk_formatXML('alert_fin',$tableau['end']);
    $xml .= sdk_formatXML('alert_debut_hloc',sdk_hloc($tableau['start'],$delta_h,'date'));
    $xml .= sdk_formatXML('alert_fin_hloc',sdk_hloc($tableau['end'],$delta_h,'date'));
    $xml .= sdk_formatXML('description',$tableau['description']);
    $xml .= sdk_formatXML('values','_end').PHP_EOL;
    $xml .= sdk_formatXML('tags','_beg','long').PHP_EOL; 
    if (array_key_exists('0',$tableau['tags'])){
      foreach($tableau['tags'] as $cle => $elem){
        $xml .= sdk_formatXML('values','_beg');
        $xml .= sdk_formatXML('tag'.$cle,$elem);
        $xml .= sdk_formatXML('values','_end').PHP_EOL;
      }
    }
    else {
      $xml .= sdk_formatXML('values','_beg');
      $xml .= sdk_formatXML('tag0','notags');
      $xml .= sdk_formatXML('values','_end').PHP_EOL;
    }
    $xml .= sdk_formatXML('tags','_end','long').PHP_EOL;
    return $xml;
}// function sdk_alertsXML

//***************** formatXML donnee
function sdk_formatXML($tag,$value,$formatXML = 'default') {// Formattage XML
  global $format;
  if ($formatXML == 'default') $formatXML = $format;
 
  if ($value === 0) $value = '_0';
  if ($value === null) $value = '_?_?';

  switch ($formatXML) {
      case 'long'  : switch ($value) {
                       case '_?_?'  : $xml = '<'.$tag.'></'.$tag.'>';break;
                       case '_0'    : '<'.$tag.'>0</'.$tag.'>';break;
                       case '_beg'  : $xml = '<'.$tag.'>';break;
                       case '_end'  : $xml = '</'.$tag.'>';break;
                       default      : $xml = '<'.$tag.'>'.$value.'</'.$tag.'>';
                     }
                     break;
      default      : switch ($value) {
                       case '_?_?'  : $xml = $tag.'="_" ';break;
                       case '_0'    : $xml = $tag.'="0" ';break;
                       case '_beg'  : $xml = '<'.$tag.' ';break;
                       case '_end'  : $xml = '/>';break;
                       default      : $xml = $tag.'="'.$value.'" ';
                     }
  }
  return $xml;
}// function sdk_formatXML

//***************** formattableauXML donnees
function sdk_formatTableauXML(&$tableau,$formatXML = 'default') {// Formattage XML
  global $format;
  global $delta_h;
  global $jours_fr;
  //global $xml; //opa95

  if ($formatXML == 'default') $formatXML = $format;
  if ($tableau['dt'] == ERRCODE) {   
    $local_time = ERRCODE;
    $jour_fr = ERRTXT;
  }
  else {
    $local_time = $tableau['dt'] + $delta_h;//correction d'heure locale
    $jour_fr = $jours_fr[date('w',$local_time)];
  }   
  $xml .= sdk_formatXML('num',$tableau['num']);
  $xml .= sdk_formatXML('nom',$tableau['nom']);
  $xml .= sdk_formatXML('dt',$tableau['dt']);
  if ($local_time == ERRCODE) {
    $xml .= sdk_formatXML('date_loc_str',ERRTXT);
    $xml .= sdk_formatXML('heure_loc_str',ERRTXT);
    $xml .= sdk_formatXML('jour_loc_semaine',ERRCODE);//dimanche = 0
    $xml .= sdk_formatXML('jour_loc_fr',ERRTXT);
  }
  else {
    $xml .= sdk_formatXML('date_loc_str',date('Y',$local_time) . '-' . date('m',$local_time).'-'.date('d',$local_time));
    $xml .= sdk_formatXML('heure_loc_str',date('G',$local_time) . ':' . date('i',$local_time));
    $xml .= sdk_formatXML('jour_loc_semaine',date('w',$local_time));//dimanche = 0
    $xml .= sdk_formatXML('jour_loc_fr',$jours_fr[date('w',$local_time)]);
  }
  $xml .= sdk_formatXML('sunrise',$tableau['sunrise']);
  $xml .= sdk_formatXML('sunset',$tableau['sunset']);
  $xml .= sdk_formatXML('sunrise_hloc',sdk_hloc($tableau['sunrise'],$delta_h,'date'));
  $xml .= sdk_formatXML('sunset_hloc',sdk_hloc($tableau['sunset'],$delta_h,'date'));
  $xml .= sdk_formatXML('moonrise',$tableau['moonrise']);
  $xml .= sdk_formatXML('moonset',$tableau['moonset']);
  $xml .= sdk_formatXML('moonrise_hloc',sdk_hloc($tableau['moonrise'],$delta_h,'date'));
  $xml .= sdk_formatXML('moonset_hloc',sdk_hloc($tableau['moonset'],$delta_h,'date'));
  $xml .= sdk_formatXML('moon_phase',$tableau['moon_phase']);
  $xml .= sdk_formatXML('night',$tableau['night']);
     
  if (array_key_exists('temperature',$tableau)) {$xml .= sdk_formatXML('temperature',$tableau['temperature']);}
  else {$xml .= sdk_formatXML('temperature',$tableau['temp']);}
  $xml .= sdk_formatXML('temp_morn',$tableau['temp_morn']);
  $xml .= sdk_formatXML('temp_day',$tableau['temp_day']);
  $xml .= sdk_formatXML('temp_eve',$tableau['temp_eve']);
  $xml .= sdk_formatXML('temp_night',$tableau['temp_night']);
  $xml .= sdk_formatXML('temp_min',$tableau['temp_min']);
  $xml .= sdk_formatXML('temp_max',$tableau['temp_max']);
  $xml .= sdk_formatXML('feels_like',$tableau['feels_like']);
  $xml .= sdk_formatXML('temp_like_morn',$tableau['like_morn']);
  $xml .= sdk_formatXML('temp_like_day',$tableau['like_day']);
  $xml .= sdk_formatXML('temp_like_eve',$tableau['like_eve']);
  $xml .= sdk_formatXML('temp_like_night',$tableau['like_night']);
  $xml .= sdk_formatXML('pressure',$tableau['pressure']);
  $xml .= sdk_formatXML('humidity',$tableau['humidity']);
  $xml .= sdk_formatXML('dew_point',$tableau['dew_point']);
  $xml .= sdk_formatXML('wind_speed',$tableau['wind_speed']);
  $xml .= sdk_formatXML('wind_gust',$tableau['wind_gust']);
  $xml .= sdk_formatXML('wind_deg',$tableau['wind_deg']);
  $xml .= sdk_formatXML('clouds',$tableau['clouds']);
  $xml .= sdk_formatXML('uvi',$tableau['uvi']);
  $xml .= sdk_formatXML('visibility',$tableau['visibility']);
  $xml .= sdk_formatXML('pop',$tableau['pop']);
  if (array_key_exists('1h',$tableau['rain'])) $xml .= sdk_formatXML('rain',$tableau['rain']['1h']);
  else $xml .= sdk_formatXML('rain',$tableau['rain']);
  if (array_key_exists('1h',$tableau['snow'])) $xml .= sdk_formatXML('snow',$tableau['snow']['1h']);
  else $xml .= sdk_formatXML('snow',$tableau['snow']);
  if ($tableau['night'] && ($tableau['weather'][0]['id'] == 800)) $tableau['weather'][0]['id'] = 900;//autres champs non remis � jour
  $xml .= sdk_formatXML('weather_id',$tableau['weather'][0]['id']);
  $xml .= sdk_formatXML('weather_main',$tableau['weather'][0]['main']);
  $xml .= sdk_formatXML('weather_desc',$tableau['weather'][0]['description']);
//     $xml .= sdk_formatXML('weather_icon',$tableau['weather'][0]['icon']);
//var_dump($xml);
  return $xml;
}// function sdk_formatTableauXML

//***************** fonction lecture commune
function sdk_getCity(&$city) {// renvoi true si $*city est valide
  global $debug;
  global $key;

  $url_GPS    = 'http://api.openweathermap.org/geo/1.0/';
  $url_GPS_fr = 'http://api-adresse.data.gouv.fr/';

// r�cuperation des donn�es de la cha�ne de commande
  $commune  = getArg('commune');
  $state_   = getArg('state',false,VOID);
  $country_ = getArg('country',false,VOID);
  if ( ($country_ == VOID) && ($state_ != VOID) ) {$country_ = $state_; $state_ = VOID;}
  if (strpos($country_,SEPMODE) !== false) $country_ = DEFCOUNTRY;
// traitement des donn�es state,country de la cha�ne
  $tab_country = explode(SEPCOORD,$country_);
  if (count($tab_country) >1) {// $country_ : state,country
    $state_   = $tab_country[0];
    $country_ = $tab_country[1];
  }
  $country_ = strtoupper($country_);//ISO 3166-1 en majuscules (2 lettres)
  if (($country_=="") or (strpos($country_,'.') != 0)) {$country_=DEFCOUNTRY;}
  $state   = utf8_encode($state_);

// traitement de commune
// forme lat,lon ou lat,lon,country ou lat,lon,state,country count 2 ou 3 ou 4 (state inutile)
// forme name ou name,country ou name,state,country name,zip,country
// forme zip ou zip,country ou zip,state,country
  $localization = explode(SEPCOORD,$commune);
  $nbr_element  = count($localization);

  if ($nbr_element == 1) { //commune : name (pas de chiffres) ou zip (au moins un chiffre)
    $test = preg_replace("/[0-9]/","",$localization[0]);//suppression des chiffres
   if ($test == $localization[0]) {
     $type_commune = "name";
     $city['name'] = utf8_encode($localization[0]);}
   else {
     $type_commune = "zip";
     $city['zip']  = strtoupper($localization[0]);
   }
  }
  else {// 2 elements ou plus
   if ( strpos($localization[1],'.') !== false) {
      //second �l�ment nombre r��l commune : lat,lon ou lat,lon,country ou lat,lan,state,country
      $type_commune = "coord";
      switch ($nbr_element) {
        case 4 : $city['state']   = utf8_encode($localization[2]);
        case 3 : $city['country'] = strtoupper($localization[$nbr_element-1]);// country en fin de liste
        case 2 : $city['lat'] = sprintf("%.4f",$localization[0]);
              if (abs($city['lat']) > 90) $city['lat'] = ERRCOORD;
              $city['lon'] = sprintf("%.4f",$localization[1]);
              if (abs($city['lon']) > 180) $city['lon'] = ERRCOORD;
              $city['valid'] = ( ($city['lon'] != ERRCOORD) && ($city['lat'] != ERRCOORD));
      }
    }
  else {// commune : 2 : name,country ou name,zip ou zip,country 3 : name,state,country ou name,zip,country
    switch ($nbr_element) {//name ou zip suivi de state et country
      case 3 : $type_commune = "name";//name,state,country ou name,zip,country
               $city['name']     = utf8_encode($localization[0]);
               $city['country']  = strtoupper($localization[2]);
               $test = preg_replace("/[0-9]/","",$localization[1]);//suppression des chiffres
               if ( $test != $localization[1]) {$city['zip']  = strtoupper($localization[1]);}
               else $city['state'] = utf8_encode($localization[1]);
               break;
      case 2 : //name,country ou name,zip ou zip,country
               $test = preg_replace("/[0-9]/","",$localization[0]);//suppression des chiffres
               if ( $test != $localization[0]) {
                  $type_commune = "zip";
                  $city['zip']     = strtoupper($localization[0]);
                  $city['country'] = strtoupper($localization[1]);
                }
                else {//name,country ou name,zip
                  $type_commune    = "name";
                  $city['name']    = utf8_encode($localization[0]);
                  $test = preg_replace("/[0-9]/","",$localization[1]);//suppression des chiffres
                  if ( $test != $localization[1]) {$city['zip']  = strtoupper($localization[1]);}
                  else $city['country'] = strtoupper($localization[1]);
                }
    }
  }
}

//completer $city avec les valeurs de la cha�ne si n�cessaire
  if ($city['country'] == VOID) {
    $city['country'] = $country_;
    if ($city['country'] == VOID) {$city['country'] = DEFCOUNTRY;}
    if ($city['state'] == VOID) {$city['state'] = $state_;}
  }
  if ( (strlen($state_) > 0) && ($city['state'] != VOID) && ($city['country'] != $country_) ) {$city['state'] = VOID;} 
  if ( ($city['state'] == VOID) && ($city['country'] == $country_) ) {$city['state'] = $state_;} 

//Affichage Debug
  if ($debug) {
    var_dump($localization);
    echo "nbr_elements = ".$nbr_element." Type commune : ".$type_commune.PHP_EOL;
    echo $country_.' '.$state_.PHP_EOL;
    var_dump($city);
  }

// Recherche localisation en latitude et longitude avec API Geocoding ou $url_GPS_fr
  switch ($city['country']) {
    case 'FR' : if ($type_commune == 'coord') {
                  $requete = 'reverse/?lat='.$city['lat'].'&lon='.$city['lon'];
                }
                else {
                  $requete = 'search/?q=';
                  if ($type_commune == 'name') {
                    $requete .= $city['name'];
                    if ($city['zip'] != VOID) $requete .= '&postcode='.$city['zip'];   
                  }
                  else {$requete .= $city['zip'];}
                    }
                   $url_GPS  = $url_GPS_fr.$requete.'&limit=1';
                    $jsonResponse_GPS = httpQuery($url_GPS);
                $jsonResponse_GPS = preg_replace('/\\\\u([\da-fA-F]{4})/', '&#x\1;', $jsonResponse_GPS);
                    $GPS_ = sdk_json_decode($jsonResponse_GPS, true);
                    $GPS  = &$GPS_['features'][0];
                    if (count($GPS) > 0) {
                      $city['name'] = $GPS['properties']['city'];
                      $city['zip']  = $GPS['properties']['postcode'];
                      $city['lat']  = sprintf("%.4f",$GPS['geometry']['coordinates'][1]);
                      $city['lon']  = sprintf("%.4f",$GPS['geometry']['coordinates'][0]);
                      $contexte     = $GPS['properties']['context'];
                      $bof = explode(',',$contexte);
                      $city['state'] = trim($bof[count($bof)-1]);
                   }
//Affichage Debug
                   if ($debug) {
                  echo "url_GPS : ".$url_GPS.PHP_EOL;
                   echo "reponse : ".$jsonResponse_GPS.PHP_EOL;
                }
                if (count($GPS) > 0) {
                  $city['valid'] = ($city['lat'] != ERRCOORD) && ($city['lon'] != ERRCOORD);
//Affichage Debug
                if ($debug) {var_dump($city);}
                break;
                }
                else {$city['country'] = VOID;}// si pas en France, continuer
    default   : switch ($type_commune) {
                     case 'name'  : $requete  = 'direct?q='   . $city['name'];
                                 break;
                     case 'zip'   : $requete  = 'zip?zip='    . $city['zip'];
                    break;
                }
                if (strlen($city['state']) > 0) $requete .= SEPCOORD.$city['state'];
                $requete .= SEPCOORD.$city['country'];
                if ($type_commune == 'coord') {}
                else {
                     $url_GPS  .= $requete.'&limit=1&appid='.$key;
                  $jsonResponse_GPS = httpQuery($url_GPS);
                  $GPS_ = sdk_json_decode($jsonResponse_GPS, true);
                  if ($type_commune == 'name') {$GPS = &$GPS_[0];}
                  else {$GPS = &$GPS_;}
                  if ( ($GPS !== null) && array_key_exists('lat',$GPS) ){
                        $GPS['lat'] = sprintf("%.4f",$GPS['lat']);
                        $GPS['lon'] = sprintf("%.4f",$GPS['lon']);
                        foreach ($GPS as $cle => $value){
                               if (array_key_exists($cle,$city)) $city[$cle] = $value;
                        }
                    }
                }
              $city['valid'] = ($city['lat'] != ERRCOORD) && ($city['lon'] != ERRCOORD);
//Affichage Debug
                 if ($debug) {
                  echo "url_GPS : ".$url_GPS.PHP_EOL;
                   echo "reponse : ".$jsonResponse_GPS.PHP_EOL;
                  var_dump($city);
                 }
  }//switch
  return $city['valid'];
   
};//function sdk_getCity

//***************** programme principal
$jours_fr = array('Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi');
$alerts_on = ALERTS;// traitement des alertes

// Mode debug si &debug=1
$debug   = getArg('debug',false,DEFDEBUG);
$reloc   = getArg('reloc',false,'0');//Forcer la relocalisation
$format  = getArg('format',false,FORMATXML);//long ou short : XML �tendu ou compact

// On r�cup�re la cl� qui doit �tre sauvegard�e apr�s r�cup�ration dans le site OpenWeather

$device = getArg('device',false,DEFDEVICE);
$device = substr(strtolower($device),0,6);
if ($debug) {echo "device: ".$device.PHP_EOL;}

$null_city   = array('zip' => 0, 'name' => VOID, 'lat' => ERRCOORD, 'lon' => ERRCOORD, 'state' => VOID, 'country' => VOID, 'valid' => false);
//saisie m�moire
$buffer_name  = getArg('mem',false,BUFFERNAME);
$buffer_data  = $buffername.'_data';
$buffer_xml   = $buffername.'_xml';

$old_data = loadVariable($buffer_data);
if ($old_data == "") {
  $old_data = array ('city' => $null_city, 'input' => "", 'dju' => ERRCODE, 'days' => array(), 'hours' => array());   
}

$xml = array('commune' => ' ','erreur' => ' ', 'current' => ' ','hours' => array(), 'dju' => '','precipitation' => '', 'days' => array(), 'alertes' => '', 'qualite' =>'');//initialisation

switch ($device) {
  case 'master':
// determination du MasterData
    $now = time();//heure
    $commune = getArg('commune');
    $key     = getArg('key');
    $url = 'http://api.openweathermap.org/data/3.0/';// url du site
    $url_meteo      = $url.'onecall?';
    $url_qualiteair = $url.'air_pollution?';
    $old_xml  = "";
    $data     = array ('city' => $null_city, 'xml' => "", 'input' => $commune.';'.$country.';'.$state, 'dju' => ERRCODE, 'days' => array(), 'hours' => array());

    if ( ($data['input'] === $old_data['input']) && !$reloc ) {
      $data['city'] = $old_data['city'];
      $is_valid_city = true;
//Affichage Debug
      if ($debug) echo 'Reprise ancienne localisation'.PHP_EOL;
    }
    else {
      $is_valid_city = sdk_getCity($data['city']);
      $old_data['dju'] = ERRCODE;
//Affichage Debug
      if ($debug) echo 'Calcul nouvelle localisation'.PHP_EOL;
    }

    $lat = $data['city']['lat'];
    $lon = $data['city']['lon'];
//******************************************** Traitement de base (m�t�o)     
/* format matrice {
array(8) {
  ["lat"]
  ["lon"]
  ["timezone"*]
  ["timezone_offset"]
  ["current"]{array (14)
    ["dt"],["sunrise"],["sunset"],["temp"],["feels_like"],["pressure"],["humidity"],["dew_point"],["uvi"],["clouds"],["visibility"],["wind_speed"],["wind_deg"],["weather"][0]{["id"],["main"*],["description"*],["icon"*]},['rain'][1h],['snow'][1h]
  ["minutely"]{array(61)[0]{["dt"],["precipitation"]}}..[60]{..}}
  ["hourly"]{array(48)[0]{...}..[47]{...}}
      array(14) {["dt"],["temp"],["feels_like"],["pressure"],["humidity"],["dew_point"],["uvi"],["clouds"],["visibility"],["wind_speed"]=>,["wind_deg"],["wind_gust"],["weather"][0]{["id"],["main"*],["description"*],["icon"*]},["pop"],,['rain'][1h],['snow'][1h]
  ["daily"]{array(8)[0]{...}..[7]{...}}
      array(18) {["dt"],["sunrise"],["sunset"],["moonrise"],["moonset"],["moon_phase"],["temp"]{["day"],["min"],["max"],["night"],["eve"],["morn"]},["feels_like"]{["day"],["night"],["eve"],["morn"]},
                 ["pressure"],["humidity"],["dew_point"],["wind_speed"],["wind_deg"],["wind_gust"],["weather"][0]{["id"],["main"*],["description"*],["icon"]*},["clouds"],["pop"],["uvi"],["rain"],["snow"],]}
  ["alerts"]{["sender_name"],["event"],["start"],["end"],["description"],["tags"]...}                 
on rajoute $matrice['city'] = $city;                 
*/
    $error  = sdk_formatXML('code','_beg');
    $url_meteo  .= 'lat=' . $lat . '&lon=' . $lon. '&units=metric&lang='. DEFLANG .'&mode=Json&appid=' . $key;
    $jsonResponse_meteo = httpQuery($url_meteo, 'GET', NULL, NULL, NULL,false,false,$info,NULL);
    $matrice = sdk_json_decode($jsonResponse_meteo, true);
/*    if (array_key_exists('cod',$matrice)) {
      $error .= sdk_formatXML('retour_API_commune',$matrice['cod']);
      $error .= sdk_formatXML('message_API_commune',$matrice['message']);       
    }
    else {     
      $error .= sdk_formatXML('retour_API_commune','200');
      $error .= sdk_formatXML('message_API_commune','OK');       
    }
    */
    $errMess = 'message_API_meteo';
    $error .= sdk_formatXML('retour_API_meteo',$info['http_code']);
    switch ($info['http_code']){
        case 200 : $error .= sdk_formatXML($errMess,'OK');break;
        default  : $error .= sdk_formatXML($errMess,$matrice['message']);
    }
    $is_invalid_matrice = count($matrice) < 3;
//    $is_invalid_matrice = true;
    $gmt_offset = date('Z');
    $delta_h = $matrice['timezone_offset'] - date('Z');// ajouter � $gmt pour calcul de l'heure locale

//Affichage Debug
    if ($debug) {
      echo "url_meteo= ".$url_meteo.PHP_EOL;
      echo "reponse : ".$jsonResponse_meteo.PHP_EOL;
//      echo "reponse meteo ".$matrice['cod'].PHP_EOL;
    }

//****** Bloc commune
// Pour l'affichage, le nom ville doit etre inf�rieur � 39 caracteres, sinon couper a 39
   $nom_ville = $data['city']['name'];
   if ($data['city']['state'] != "") $nom_ville .= ' : '.$data['city']['state'];
   elseif (($data['city']['state'] != DEFCOUNTRY)) {$nom_ville .= ' : '.$data['city']['country'];}
   $nom_ville = substr($nom_ville,0,DEFAFFICHE);
   $ville_GPS = $nom_ville . " (" . round($data['city']['lat'],3) . "�, " . round($data['city']['lon'],3) . "�)";
    sdk_testNum($matrice['timezone_offset'],$is_invalid_matrice);
   if ($matrice['timezone_offset'] == ERRCODE) {$matrice['timezone'] = ERRTXT;}
    $result  = sdk_formatXML('commune','_beg');
    $result .= sdk_formatXML('city_GPS',$ville_GPS);
    $result .= sdk_formatXML('country',$data['city']['country']);;
    $result .= sdk_formatXML('state',$data['city']['state']);
    $result .= sdk_formatXML('zip',$data['city']['zip']);
    $result .= sdk_formatXML('lat',$matrice['lat']);
    $result .= sdk_formatXML('lon',$matrice['lon']);
    $result .= sdk_formatXML('timezone',$matrice['timezone']);
    $result .= sdk_formatXML('timezone_offset',$matrice['timezone_offset']);
    $xml['commune'] = $result. sdk_formatXML('commune','_end').PHP_EOL;
//Affichage Debug
    if ($debug) {echo 'Commune : '.$xml['commune'].PHP_EOL;}
//****** Fin Bloc commune

//****** Bloc alertes
    if ($alerts_on){//Lecture alertes
      $result  = sdk_formatXML('alerts','_beg','long').PHP_EOL;
      if (!array_key_exists('alerts',$matrice)){
        $matrice['alerts'][0]= array('sender_name' => 'Aucun','event' => 'Aucun','start' => ERRCODE, 'end' => ERRCODE, 'description' => VOID, 'tags' => VOID); 
        $count = count($matrice['alerts']);
        for ($num = 0; $num < $count; $num++) {
          $result .= sdk_formatXML('alerts_'.$num,'_beg','long').PHP_EOL;
          $result .= sdk_alertsXML($matrice['alerts'][$num]);
          $result .= sdk_formatXML('alerts_'.$num,'_end','long').PHP_EOL;
        }
      }
      else $result .= sdk_alertsXML('noAlert');
      $xml['alertes'] = $result.sdk_formatXML('alerts','_end','long').PHP_EOL;

//Affichage Debug
      if ($debug) {echo 'Alertes : '. $xml['alerts'].PHP_EOL;}
   }
   else $xml['alertes'] = '';//pas de lectures alertes
//****** Fin Bloc alertes

//****** Bloc daily

    for ($num=0;$num<8;$num++){
      foreach ( array('dt','sunrise','sunset','moonrise','moonset','moon_phase','pressure','visibility','humidity','dew_point','wind_speed','wind_deg','wind_gust','clouds','pop','uvi') as $cle) {
        sdk_testNum($matrice['daily'][$num][$cle],$is_invalid_matrice);
      }
      if ( ($matrice['daily'][$num]['rain'] == ERRCODE) && ($matrice['daily'][$num]['pop'] != ERRCODE) ) $matrice['daily'][$num]['rain'] == 0;
      foreach ( array('day','min','max','night','eve','morn' ) as $cle) {
        sdk_testNum($matrice['daily'][$num]['temp'][$cle],$is_invalid_matrice);
        $matrice['daily'][$num]['temp_'.$cle] = $matrice['daily'][$num]['temp'][$cle];
      }
      $matrice['daily'][$num]['temperature'] = $matrice['daily'][$num]['temp_day'];

      foreach ( array('day','night','eve','morn' ) as $cle) {
        sdk_testNum($matrice['daily'][$num]['feels_like'][$cle],$is_invalid_matrice);
        $matrice['daily'][$num]['like_'.$cle] = $matrice['daily'][$num]['feels_like'][$cle];
      }
      sdk_testWeather($matrice['daily'][$num]['weather'][0],$is_invalid_matrice);
      if ( (!array_key_exists('rain',$matrice['daily'][$num])) && ($matrice['daily'][$num]['dt'] != ERRCODE) ) $matrice['daily'][$num]['rain'] = 0;
      if ( (!array_key_exists('snow',$matrice['daily'][$num])) && ($matrice['daily'][$num]['dt'] != ERRCODE) ) $matrice['daily'][$num]['snow'] = 0;
      if ( (!array_key_exists('wind_speed',$matrice['daily'][$num])) && ($matrice['daily'][$num]['wind_speed'] != ERRCODE) ) $matrice['daily'][$num]['wind_speed'] = $matrice['daily'][$num]['wind_speed']*3.6;//km/h
      if ( (!array_key_exists('wind_gust',$matrice['daily'][$num])) && ($matrice['daily'][$num]['wind_gust'] != ERRCODE) ) $matrice['daily'][$num]['wind_gust'] = $matrice['daily'][$num]['wind_gust']*3.6;//km/h
      $night_ = (($matrice['daily'][$num]['dt'] > $matrice['daily'][$num]['sunrise']) && ($matrice['daily'][$num]['dt'] < $matrice['daily'][$num]['sunset']))? 0:1;
      if (is_invalid_matrice) {$local_time = $now + $delta_h + $num*86400;}
      else $local_time = $matrice['daily'][$num]['dt'] + $delta_h;//correction d'heure locale
      $jour_fr = $jours_fr[date('w',$local_time)];
      if ($num == 0) {$jour='auj';}
      else {$jour = $jour_fr;}
      $matrice['daily'][$num]['num']= $num;
      $matrice['daily'][$num]['nom']= strtolower(substr($jour,0,3));
      $matrice['daily'][$num]['night']= $night_;
      $data['days'][strtolower(substr($jour,0,3))] = $num;
      $result  = sdk_formatXML('day','_beg');
      $result .= sdk_formatTableauXML($matrice['daily'][$num]);
      $xml['days'][$num] = $result.sdk_formatXML('day','_end').PHP_EOL; 
    }

//Affichage Debug
    if ($debug) {
      echo 'daily : '.PHP_EOL;
      var_dump($matrice['daily']);
      var_dump($xml['days']);
    }
//****** Fin Bloc daily

//****** Bloc precipitation et minutly
// Pour l'affichage, le nom ville doit etre inf�rieur � 39 caracteres, sinon couper a 39
   
    for ($num=0;$num<61;$num++){
      sdk_testNum($matrice['minutely'][$num]['dt'],$is_invalid_matrice);
      sdk_testNum($matrice['minutely'][$num]['precipitation'],$is_invalid_matrice);
    }
   $stop_rain  = $now - 60;//-1minute
   $start_rain = $now + 7200;//2h
   $rain  = false;
    $is_raining = false;
   for ($ind = 0,$total_rain=0; $ind <= 60; $ind++) {
      if ($matrice['minutely'][$ind]['precipitation'] == ERRCODE) {
        $total_rain = ERRCODE; break;
      }
      elseif ($matrice['minutely'][$ind]['precipitation'] != 0){
        if (!$is_raining) {$rain = true; $is_raining = true; $start_rain = $matrice['minutely'][$ind]['dt'];}
        else {
          $total_rain += $matrice['minutely'][$ind]['precipitation'];
          if ($matrice['minutely'][$ind]['dt'] < $start_rain) {$start_rain = $matrice['minutely'][$ind]['dt'];}
        }
      }
      else {//precipitation == 0
        if ($is_raining) {$is_raining = false; $stop_rain = $matrice['minutely'][$ind]['dt'];break;}
        else {}
      }
    }
    if ($is_raining) {$stop_rain = $matrice['minutely'][60]['dt'];}// pas d'arret de la pluie
    if (!$rain){$start_rain = $now; $stop_rain = $now + 3600;}

    $result  = sdk_formatXML('precipitation','_beg');
    $result .= sdk_formatXML('averse_hauteur',$total_rain);
    $result .= sdk_formatXML('averse_duree',round(($stop_rain-$start_rain)/60));
    $result .= sdk_formatXML('averse_debut_hloc',sdk_hloc($start_rain,$delta_h));
    $result .= sdk_formatXML('averse_fin_hloc',sdk_hloc($stop_rain,$delta_h));
    $xml['precipitation'] = $result.sdk_formatXML('precipitation','_end').PHP_EOL;
   
//Affichage Debug
    if ($debug) {echo 'precipitation : '.$xml['precipitation'].PHP_EOL;}
//****** Fin Bloc precipitation

//****** Bloc prevision hourly 0 � 47
//calcul DJU
    $dju_Tmin = 100;// Temperature minimale de J-1(18h) � J (18h)
    $min_start = -1;
    $dju_Tmax = -100;// Temperature maximale de J(6h) � J+1 (6h)
    $max_start = -1;
    $day_parts = array(0 =>'night',1 =>'morn', 2 =>'day',3 =>'eve');
    $temp_ = array ('morn'=>ERRCODE,'day'=>ERRCODE,'eve'=>ERRCODE,'night'=>ERRCODE);
    $like_ = array ('morn'=>ERRCODE,'day'=>ERRCODE,'eve'=>ERRCODE,'night'=>ERRCODE);

    for ($num=0;$num<48;$num++){
      $local_time = $matrice['hourly'][$num]['dt'] + $delta_h;//correction d'heure locale
      $jour_loc_semaine = date('w',$local_time);//dimanche = 0
      $delta_day        = $jour_loc_semaine - $jour_loc_sem;
      $heure = date('G',$local_time);
      if ($num == 0) {$numh = 'now';}
      elseif ($num <= 24) {$numh = $heure;} 
      else {$numh = SEPHEURE.$heure;}
      $night_ = ( (($matrice['hourly'][$num]['dt'] > $matrice['daily'][0]['sunrise']) && ($matrice['hourly'][$num]['dt'] < $matrice['daily'][0]['sunset'])) || (($matrice['hourly'][$num]['dt'] > $matrice['daily'][1]['sunrise']) && ($matrice['hourly'][$num]['dt'] < $matrice['daily'][1]['sunset'])) || (($matrice['hourly'][$num]['dt'] > $matrice['daily'][2]['sunrise']) && ($matrice['hourly'][$num]['dt'] < $matrice['daily'][2]['sunset'])))? 0:1;
      $day_part_num =    (floor( (date('G',$local_time) + 1)/6))%4;
      $day_part = $day_parts[$day_part_num];
      $matrice['hourly'][$num]['num']   = $num;
      $matrice['hourly'][$num]['nom']   = strtolower(substr($numh,0,3));
      $data['hours'][strtolower(substr($numh,0,3))] = $num;

      $matrice['hourly'][$num]['night'] = $night_;
      if ($temp_[$day_part] == ERRCODE) {
        $temp_[$day_part] = $matrice['hourly'][$num]['temp'];
        $like_[$day_part] = $matrice['hourly'][$num]['feels_like'];
      }
      $matrice['hourly'][$num]['sunrise']    = $matrice['daily'][$delta_day]['sunrise'];
      $matrice['hourly'][$num]['sunrise']    = $matrice['daily'][$delta_day]['sunrise'];
      $matrice['hourly'][$num]['sunset']     = $matrice['daily'][$delta_day]['sunset'];
      $matrice['hourly'][$num]['moonrise']   = $matrice['daily'][$delta_day]['moonrise'];
      $matrice['hourly'][$num]['moonset']    = $matrice['daily'][$delta_day]['moonset'];
      $matrice['hourly'][$num]['moon_phase'] = $matrice['daily'][$delta_day]['moon_phase'];
      foreach ( array('dt','temp','feels_like','pressure','humidity','dew_point','uvi','clouds','visibility','wind_speed','wind_deg','wind_gust','pop') as $cle) {
        sdk_testNum($matrice['hourly'][$num][$cle],$is_invalid_matrice);
      }
      sdk_testWeather($matrice['hourly'][$num]['weather'][0],$is_invalid_matrice);
      if ( !(array_key_exists('rain',$matrice['hourly'][$num])) && ($matrice['hourly'][$num]['dt'] != ERRCODE) ) $matrice['hourly'][$num]['rain']['1h'] = 0;
      if ( !(array_key_exists('snow',$matrice['hourly'][$num])) && ($matrice['hourly'][$num]['dt'] != ERRCODE) ) $matrice['hourly'][$num]['snow']['1h'] = 0;

      if ( ($min_start < 0)  && ($numh == 18) && ($num < 24) ) {$min_start = $num; $min_stop = $min_start + 18;}
      if ( ($min_start >= 0) && ($num < $min_stop) && ($matrice['hourly'][$num]['temp'] != ERRCODE) ) {$dju_Tmin = min($dju_Tmin,$matrice['hourly'][$num]['temp']);}
      if ( ($min_start >= 0) && ($max_start < 0) && ($numh == 6) && ($num >= 12) ) {$max_start = $num; $max_stop = $max_start + 18;}
      if ( ($max_start >= 0) && ($num < $max_stop) && ($matrice['hourly'][$num]['temp'] != ERRCODE)  ) {$dju_Tmax = max($dju_Tmax,$matrice['hourly'][$num]['temp']);}
    }

    for ($num=0;$num<48;$num++){
      $numh = $matrice['hourly'][$num]['nom'];
      $numh = str_replace(SEPHEURE,'',$numh);
      if ($numh == 'now') $numh = $heure_;
      $day_part_num =    (floor( (date('G',$numh) + 1)/6))%4;
      $day_part     = $day_parts[$day_part_num];
      foreach ($temp_ as $cle => $value) {
        if ($value != ERRCODE) {
          $matrice['hourly'][$num]['temp_'.$cle] = $value;
          $matrice['hourly'][$num]['like_'.$cle] = $like_[$cle];
        }
      }
      $result  = sdk_formatXML('hour','_beg');
      $result .= sdk_formatTableauXML($matrice['hourly'][$num]);
      $xml['hours'][$num] = $result.sdk_formatXML('hour','_end').PHP_EOL; 
    }

    if ($dju_Tmin > $dju_Tmax){$dju = $old_dju;}//invalide
    else {
      $dju_Tmin = min($dju_Tmin,DJUREF);
      $dju_Tmax = min($dju_Tmax,DJUREF);
      $dju = DJUREF - ($dju_Tmin + $dju_Tmax)/2;
    }
    $result  = sdk_formatXML('dju','_beg');
    $result .= sdk_formatXML('dju_prev',$dju);
    $result .= sdk_formatXML('dju_tmin',$dju_Tmin);
    $result .= sdk_formatXML('dju_tmax',$dju_Tmax);
    $xml['dju'] = $result.sdk_formatXML('dju','_end').PHP_EOL;

     $xml_        .= sdk_formatXML('hourly','_end','long').PHP_EOL;
     
//Affichage Debug
    if ($debug) {
      echo 'hourly : '.PHP_EOL;
      var_dump($matrice['hourly']);
      var_dump($xml['hor']);
      echo 'dju '.$xml['dju'].PHP_EOL;
    }
//****** Fin Bloc hourly et dju

//****** Bloc current
    foreach ( array('dt','sunrise','sunset','temp','feels_like','pressure','humidity','dew_point','uvi','clouds','visibility','wind_speed','wind_deg') as $cle) {
      sdk_testNum($matrice['current'][$cle],$is_invalid_matrice);
    }
    if ( (!array_key_exists('rain',$matrice['current'])) && ($matrice['current']['dt'] != ERRCODE) ) $matrice['current']['rain']['1h'] = 0;
    if ( (!array_key_exists('snow',$matrice['current'])) && ($matrice['current']['dt'] != ERRCODE) ) $matrice['current']['snow']['1h'] = 0;
    sdk_testWeather($matrice['current']['weather'][0],$is_invalid_matrice);
    $matrice['current']['num'] = 0;
    $matrice['current']['nom'] = 'now';
    $matrice['current']['moonrise']   = $matrice['daily'][0]['moonrise'];
    $matrice['current']['moonset']    = $matrice['daily'][0]['moonset'];
    $matrice['current']['moon_phase'] = $matrice['daily'][0]['moon_phase'];
    $night_ = (($matrice['current']['dt'] > $matrice['current']['sunrise']) && ($matrice['current']['dt'] < $matrice['current']['sunset']))? 0:1;
    $matrice['current']['night'] = $night_;
    foreach (array('morn','day','eve','night','min','max') as $cle){
      $matrice['current']['temp_'.$cle] = $matrice['daily'][0]['temp'][$cle];
    }
    foreach (array('morn','day','eve','night') as $cle){
      $matrice['current']['like_'.$cle] = $matrice['daily'][0]['feels_like'][$cle];
    }
    foreach (array('wind_gust','pop','rain','snow') as $cle){   
      $matrice['current'][$cle] = $matrice['hourly'][0][$cle];
    }

    $result  = sdk_formatXML('current','_beg');
    $result .= sdk_formatTableauXML($matrice['current']);
    $xml['current'] = $result.sdk_formatXML('current','_end').PHP_EOL; 
//Affichage Debug
    if ($debug) {
        echo 'current : '.$xml.PHP_EOL;
        var_dump($matrice['current']);
    }
//****** Fin Bloc current

//******************************************** Traitement qualit� air     
/* format content array(5) {     
["coord"]{["lon"],["lat"]}
["list"][0]["main"]["aqi"]
           ["components"]{["co"],["no"],["no2"],["o3"],["so2"],["pm2_5"],["pm10"],["nh3"]},
           ["dt"]}     
*/
// Envoi de la requete pour qualit� de l'air
// http://api.openweathermap.org/data/3.0/air_pollution?lat={lat}&lon={lon}&appid={API key}
    $url_qualiteair .= 'lat=' . $data['city']['lat'] . '&lon=' . $data['city']['lon'] . '&appid=' . $key;
    $jsonResponse_qualite = httpQuery($url_qualiteair, 'GET', NULL, NULL, NULL,false,false,$info,NULL);
    $content = sdk_json_decode($jsonResponse_qualite, true);
    $is_invalid_content = ( ($content['cod'] !== null) && (!is_numeric($content['main']['aqi'])) );
    $error .= sdk_formatXML('retour_API_qualite',$info['http_code']);
    $errMess = 'message_API_qualite';
    switch ($info['http_code']){
        case 200 : $error .= sdk_formatXML($errMess,"OK");break;
        default  : $error .= sdk_formatXML($errMess,$content['message']);
    }
   
//    $is_invalid_content = true;
    $error  .= sdk_formatXML('erreur','_end').PHP_EOL;
    $xml['erreur'] = $error;
//Affichage Debug
    if ($debug) {
      echo "url_qualiteair: ".$url_qualiteair.PHP_EOL;
      echo "reponse : ".$jsonResponse_qualite.PHP_EOL;
      var_dump($content);
    }

// V�rification des variables r�cup�r�es si pas num�rique mettre la variable � ERRCODE (-9999)
    $content['coord']['lat'] = $data['city']['lat'];
    $content['coord']['lon'] = $data['city']['lon'];
    sdk_testNum($content['list'][0]['dt'],$is_invalid_content);
    sdk_testNum($content['list'][0]['main']['aqi'],$is_invalid_content);
    foreach ( array('no','no2','o3','so2','co','pm2_5','pm10','nh3') as $cle) {
      sdk_testNum($content['list'][0]['components'][$cle],$is_invalid_content);
    }
    sdk_testNum($content['list'][0]['dt'],$is_invalid_content);

// Generation du XML pour les qualit�s
    $result  = sdk_formatXML('donnees_qualite','_beg');
    $result .= sdk_formatXML('dt',$content['list'][0]['dt']);
    $result .= sdk_formatXML('air_aqi',$content['list'][0]['main']['aqi']);
    $result .= sdk_formatXML('air_no',$content['list'][0]['components']['no']);
    $result .= sdk_formatXML('air_no2',$content['list'][0]['components']['no2']);
    $result .= sdk_formatXML('air_o3',$content['list'][0]['components']['o3']);
    $result .= sdk_formatXML('air_so2',$content['list'][0]['components']['so2']);
    $result .= sdk_formatXML('air_co',$content['list'][0]['components']['co']);
    $result .= sdk_formatXML('air_pm2_5',$content['list'][0]['components']['pm2_5']);
    $result .= sdk_formatXML('air_pm10',$content['list'][0]['components']['pm10']);
    $result .= sdk_formatXML('air_nh3',$content['list'][0]['components']['nh3']);
    $xml['qualite'] = $result.sdk_formatXML('donnees_qualite>','_end').PHP_EOL;


// Generation du XML
    sdk_header('text/xml');
    echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
    echo sdk_formatXML('donnees_meteo','_beg','long').PHP_EOL;
    echo $xml['commune'];
    echo $xml['erreur']; 
    echo $xml['current'];
    echo $xml['precipitation'];
    echo $xml['dju'];
    echo sdk_formatXML('daily','_beg','long').PHP_EOL;
    foreach ($xml['days'] as $elem) {echo $elem;}
    echo sdk_formatXML('daily','_end','long').PHP_EOL;
    echo sdk_formatXML('hourly','_beg','long').PHP_EOL;
    foreach ($xml['hours'] as $elem) {echo $elem;}
    echo sdk_formatXML('hourly','_end','long').PHP_EOL;   
    echo $xml['qualite'];
    echo sdk_formatXML('donnees_meteo','_end','long').PHP_EOL;
   
    if ($buffer_xml != NOMEM.'xml') {
        saveVariable($buffer_data,$data);
        saveVariable($buffer_xml,$xml);
    }
    break;//fin MasterData
  default:
// modes : _all, _com, _err, _cur, _pre, _alr, _dju, _day, _hor, _qua, _j0 .. _j7, _dim .. _sam,
    $mode  = array ('com' => 1,'err' => 1,'cur' => 1,'pre' => 1,'alr' => 1,'dju' => 1,'qua' => 1,'day' => 1,'hor' => 1);
    $days  = array ();
    for ($num =0;$num<8;$num++) {$days[$num] = 1;}
    $hours = array();
    for ($num =0;$num<48;$num++) {$hours[$num] = 1;}
    $state_ = getArg('state',false,VOID);//retrocompatibilite
    $mode_  = getArg('country',false,VOID);
    if ( ($mode_ == VOID) && ($state_ != VOID) ) {$mode_ = $state_;}//retrocompatibilite
    $_mode_ = getArg('mode',false,VOID);
    if ($_mode_ !== VOID) $mode_ = $_mode_;
    $periph_id = getArg('periph_id',false);
    $values = getValue($periph_id);
    $choix_ = $values['value'];
    $choix = array (0=>'auj','1J','2J','3J','4J','5J','6J','7J',
                    100=> 'dim','lun','mar','mer','jeu','ven','sam',
                    200=> '0H','1H','2H','3H','4H','5H','6H','7H','8H','9H','10H','11H',
                         '12H','13H','14H','15H','16H','17H','18H','19H','20H','21H','22H','23H','24H',
                    300=> '0','1','2','3','4','4','6','7','8','9','10','11','12',
                          '13','14','15','16','17','18','19','20','21','22','23');
    if ($choix[$choix_]) $mode_ = SEPMODE.$choix[$choix_];
    $mode_ = strtolower($mode_);
    $modeXML = $mode_;
    if (strpos($mode_,SEPMODE) !== false) {
      foreach ($mode as $cle => $elem){//modes complets
        if (strpos($mode_,SEPMODE.$cle) === false) {$mode[$cle] = 0;}
        else $mode_ = str_replace(SEPMODE.$cle,'',$mode_);
      }
      if (!$mode['day']){
        foreach ($days as $cle => $elem){
          if (strpos($mode_,SEPMODE.$cle.SUFFJ) === false) {$days[$cle] = 0;}
          else {
            $mode_ = str_replace(SEPMODE.$cle.SUFFJ,'',$mode_);
            $mode['day'] = 1;
          }
        }
      }
      if (!$mode['hor']){
        foreach ($hours as $cle => $elem){
          if (strpos($mode_,SEPMODE.$cle.SUFFH) === false) {$hours[$cle] = 0;}
          else {
            $mode_ = str_replace(SEPMODE.$cle.SUFFH,'',$mode_);
            $mode['hor'] = 1;
          }
        }
      }
      if (strpos($mode_,SEPMODE) !== false) {
        $mode_ = substr($mode_,1);
        $mode__ = explode(SEPMODE,$mode_);
        foreach ($mode__ as $cle) {
          if (array_key_exists($cle,$old_data['days'])) {
            $elem = $old_data['days'][$cle];
            $days[$elem] = 1;
            $mode['day'] = 1;
          }
          if (array_key_exists($cle,$old_data['hours'])) {
            $elem = $old_data['hours'][$cle];
            $hours[$elem] = 1;
            $mode['hor'] = 1;
          }
        }
      }
    }
  $xml = loadVariable($buffer_xml);
// debug
  if ($debug) {
    echo 'mode - ';var_dump($mode);
    echo 'days - ';var_dump($days);
    echo 'old_data[days] - ';var_dump($old_data['days']);
    echo 'hours - ';var_dump($hours);
    echo 'old_data[hours] - ';var_dump($old_data['hours']);
    echo 'xml[days] - ';var_dump($xml['days']);
    echo 'xml[hours] - ';var_dump($xml['hours']);
  }   
    sdk_header('text/xml');
    echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
    echo sdk_formatXML('donnees_meteo','_beg','long').PHP_EOL;
    echo '<modes mode="'.$modeXML.'" />'.PHP_EOL;
    if ($mode['com']) echo $xml['commune'];
    if ($mode['err']) echo $xml['erreur'];
    if ($mode['cur']) echo $xml['current'];
    if ($mode['pre']) echo $xml['precipitation'];
    if ($mode['alr']) echo $xml['alertes'];
    if ($mode['dju']) echo $xml['dju'];
    if ($mode['day']) {
      echo sdk_formatXML('daily','_beg','long').PHP_EOL;
      foreach ($days as $cle => $elem) {
//        echo $cle.' : '.$cle.SUFFJ.' : '.$elem.' = '.$days[$cle].' ; ';
        if ($days[$cle]) {echo $xml['days'][$cle];}
      }
      echo sdk_formatXML('daily','_end','long').PHP_EOL;
    }
    if ($mode['hor']) {
      echo sdk_formatXML('hourly','_beg','long').PHP_EOL;
      foreach ($hours as $cle => $elem) {
//        echo $cle.' = '.$elem.' : '.PHP_EOL;
        if ($hours[$cle]) {echo $xml['hours'][$cle];}
//        if ($elem) {echo $xml[str_replace(SUFFH,'',$cle)];}
      }
      echo sdk_formatXML('hourly','_end','long').PHP_EOL;
    }
    if ($mode['qua']) echo $xml['qualite'];
    echo sdk_formatXML('donnees_meteo','_end','long').PHP_EOL;
    break;
  }
?>
eedomus+, Zibase V1, RFP1000, RFXcom, RadioDriver CPL 630 X2D, capteurs puissance OWL, thermometres Oregon, téléinfo (USB Linky), detecteurs ouverture X2D, pilotage chauffage X2D, Ecoflow River PRO, PAC Shogun (Atlantic-Cozytouch)
opa95
 
Messages : 977
Inscription : 04 Fév 2019
Localisation : Val d'Oise

Re: script 'open weather'

Messagepar flouret » 17 Jan 2026 10:03

Bonjour,
Ok, je modifie ces 2 lignes et je te tiens au courant
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Re: script 'open weather'

Messagepar flouret » 17 Jan 2026 10:09

Ok super merci
Bizarre cette modification
flouret
 
Messages : 201
Inscription : 29 Jan 2019

Suivant

Retour vers Scripts & Périphériques du store

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 19 invité(s)