diff --git a/Sources/app/build.gradle b/Sources/app/build.gradle
index 29fabad836482ce62a3c0b2272fb6816a04e0ee1..607feaf34e7686f5b299e121e3e217cfda83b8d0 100644
--- a/Sources/app/build.gradle
+++ b/Sources/app/build.gradle
@@ -32,6 +32,7 @@ dependencies {
     implementation 'androidx.appcompat:appcompat:1.5.1'
     implementation 'com.google.android.material:material:1.6.1'
     implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+    implementation 'com.google.android.gms:play-services-location:20.0.0'
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/Sources/app/src/main/AndroidManifest.xml b/Sources/app/src/main/AndroidManifest.xml
index f45be7463c3ea8d9ddcb7ea323d2838848ed2e7d..200daf11fbe293d6a3c60f010e8743c6981fc14a 100644
--- a/Sources/app/src/main/AndroidManifest.xml
+++ b/Sources/app/src/main/AndroidManifest.xml
@@ -9,7 +9,7 @@
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-
+    <uses-permission android:name="android.permission.INTERNET" />
     <uses-feature android:name="android.hardware.location.gps" />
 
     <application
@@ -20,6 +20,7 @@
         android:label="@string/app_name"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
+        android:usesCleartextTraffic="true"
         android:theme="@style/Theme.RoomView"
         tools:targetApi="31">
         <activity
diff --git a/Sources/app/src/main/java/Common/ImageManager.java b/Sources/app/src/main/java/Common/ImageManager.java
index 3d6db2bd4da336a8fed199631f7327a911ed0e17..ee139f4227b86c64e5031717a22e57e4214ba7ea 100644
--- a/Sources/app/src/main/java/Common/ImageManager.java
+++ b/Sources/app/src/main/java/Common/ImageManager.java
@@ -1,11 +1,16 @@
 package Common;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.widget.Toast;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import Structures.BuildingInfo;
 import Structures.PhotoInfo;
@@ -13,51 +18,17 @@ import Structures.RoomInfo;
 import Structures.ZoneInfo;
 
 public class ImageManager {
-    private static File saveDir;
-    private static Context context = null;
-
-    public static void setContext(Context c) {
-        context = c;
-        saveDir = context.getFilesDir();
-    }
-
-    public static boolean saveImage(byte[] data, PhotoInfo photo) {
-        boolean res = true;
-        File imgFile = getImageFile(photo);
-        try {
-            FileOutputStream fos = new FileOutputStream(imgFile);
-            fos.write(data);
-            fos.close();
-            res = true;
-        } catch (Exception e) {
-            res = false;
-        }
-        return res;
-    }
-
-    public static byte[] getImage(PhotoInfo photo) {
-        byte[] res = new byte[0];
-        File imgFile = getImageFile(photo);
-        try {
-            FileInputStream fis = new FileInputStream(imgFile);
-            int length = (int) imgFile.length();
-            res = new byte[length];
-            fis.read(res, 0, length);
-            fis.close();
-        } catch (Exception ignored) {}
-        return res;
-    }
-
-    protected static String getImagePath(PhotoInfo photo) {
-        ZoneInfo zone = photo.getZone();
-        RoomInfo room = zone.getRoom();
-        BuildingInfo building = room.getBuilding();
-        return "img-"+building.getName()+"-"+room.getName()+"-"+zone.getName()+"-"+photo.getOrientation()+".png";
-    }
-
-    protected static File getImageFile(PhotoInfo photo) {
-        String abs_path = saveDir + getImagePath(photo);
-        Toast.makeText(context, "saved to "+abs_path, Toast.LENGTH_SHORT).show();
-        return new File(abs_path);
+    public static void bitmapFromURL(Callback onResolve, Callback onReject, String url) {
+        ExecutorService service = Executors.newSingleThreadExecutor();
+        service.execute(() -> {
+            Bitmap icon = null;
+            try {
+                InputStream in = new java.net.URL(url).openConnection().getInputStream();
+                icon = BitmapFactory.decodeStream(in);
+                onResolve.call(icon);
+            } catch (Exception e) {
+                onReject.call("Image decode error : (image: "+url+")" + e.getMessage());
+            }
+        });
     }
 }
diff --git a/Sources/app/src/main/java/Common/Position.java b/Sources/app/src/main/java/Common/Position.java
new file mode 100644
index 0000000000000000000000000000000000000000..5eb0e619ade63933507c3bca77654559c5ac2c5f
--- /dev/null
+++ b/Sources/app/src/main/java/Common/Position.java
@@ -0,0 +1,33 @@
+package Common;
+
+import android.location.Location;
+
+import java.io.Serializable;
+
+public class Position implements Serializable {
+    public double latitude;
+    public double longitude;
+
+    public Position(double latitude, double longitude) {
+        this.latitude = latitude;
+        this.longitude = longitude;
+    }
+
+    public Position(Location location) {
+        this.latitude = location.getLatitude();
+        this.longitude = location.getLongitude();
+    }
+
+    public Position() {
+        this.latitude = 0;
+        this.longitude = 0;
+    }
+
+    public double getLatitude() {
+        return latitude;
+    }
+
+    public double getLongitude() {
+        return longitude;
+    }
+}
\ No newline at end of file
diff --git a/Sources/app/src/main/java/Popups/PhotoInfoPopup.java b/Sources/app/src/main/java/Popups/PhotoInfoPopup.java
index 324da13dc6a0345cd25944a822875741a1666f86..b739e3134f2c89f1a61df9ea7a7b033193ebf29a 100644
--- a/Sources/app/src/main/java/Popups/PhotoInfoPopup.java
+++ b/Sources/app/src/main/java/Popups/PhotoInfoPopup.java
@@ -14,6 +14,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 
 import Common.Callback;
+import Structures.MeteoInfo;
 import Structures.PhotoInfo;
 
 public class PhotoInfoPopup {
@@ -23,6 +24,15 @@ public class PhotoInfoPopup {
     AlertDialog dialog = null;
     Button validate_btn = null;
 
+    private void setText(int id, String text) {
+        TextView tv = dialog.findViewById(id);
+        if (text == null || text.isEmpty()) {
+            tv.setText("");
+        } else {
+            tv.setText(text);
+        }
+    }
+
     public PhotoInfoPopup(Context context, PhotoInfo photo) {
         AlertDialog.Builder builder = new AlertDialog.Builder(context);
         dialog = builder.create();
@@ -31,11 +41,15 @@ public class PhotoInfoPopup {
         dialog.setView(popup);
 
         dialog.setOnShowListener(dialogInterface -> {
-            TextView tv_hour = popup.findViewById(R.id.photo_hour);
-            TextView tv_date = popup.findViewById(R.id.photo_date);
             Date d = photo.getDate();
-            tv_hour.setText(new SimpleDateFormat("HH:mm").format(d));
-            tv_date.setText(new SimpleDateFormat("yyyy / MM / dd").format(d));
+            setText(R.id.photo_hour, new SimpleDateFormat("HH:mm").format(d));
+            setText(R.id.photo_date, new SimpleDateFormat("yyyy / MM / dd").format(d));
+
+            MeteoInfo meteo = photo.getMeteo();
+            setText(R.id.photo_temp, Math.round(meteo.getTemperature()) + " °C");
+            setText(R.id.photo_humidity, (int)meteo.getHumidity() + " %");
+            setText(R.id.photo_pressure, (int)(meteo.getPressure() * 1000) + " hPa");
+            setText(R.id.photo_weather, MeteoInfo.weatherToString(meteo.getWeather()));
 
             validate_btn = popup.findViewById(R.id.btn_validate_room);
             validate_btn.setOnClickListener(view -> this.dismiss());
diff --git a/Sources/app/src/main/java/Structures/MeteoInfo.java b/Sources/app/src/main/java/Structures/MeteoInfo.java
index 42225ad33c28f0c882173e9d41acd63c95858580..a0ff7142f5040ebc955af19af5434b6afecc5907 100644
--- a/Sources/app/src/main/java/Structures/MeteoInfo.java
+++ b/Sources/app/src/main/java/Structures/MeteoInfo.java
@@ -1,22 +1,283 @@
 package Structures;
 
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import androidx.core.app.ActivityCompat;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import Common.BuildingManager;
+import Common.Callback;
+import Common.ImageManager;
+import Common.Position;
+
+import com.furwaz.roomview.PhotoActivity;
+import com.furwaz.roomview.R;
+import com.google.android.gms.location.FusedLocationProviderClient;
+
+import org.json.JSONObject;
 
 public class MeteoInfo implements Serializable {
-    public static MeteoInfo GetCurrentMeteo() {
-        // TODO
-        return null;
+    enum WeatherType {
+        CLEAR_SKY,
+        FEW_CLOUDS,
+        SCATTERED_CLOUDS,
+        BROKEN_CLOUDS,
+        SHOWER_RAIN,
+        RAIN,
+        THUNDERSTORM,
+        SNOW,
+        MIST
+    }
+
+    public static WeatherType WeatherFromString(String s) {
+        switch (s.toLowerCase(Locale.ROOT)) {
+            case "clouds": return WeatherType.FEW_CLOUDS;
+            case "rain": return WeatherType.RAIN;
+            case "thunderstorm": return WeatherType.THUNDERSTORM;
+            case "snow": return WeatherType.SNOW;
+            case "mist": return WeatherType.MIST;
+            default: return WeatherType.CLEAR_SKY;
+        }
+    }
+
+    public static String weatherToString(WeatherType weather) {
+        if (currentActivity == null || weather == null) return "";
+
+        int id = 0;
+        switch (weather) {
+            case FEW_CLOUDS: id = R.string.few_clouds; break;
+            case SCATTERED_CLOUDS: id = R.string.scattered_clouds; break;
+            case BROKEN_CLOUDS: id = R.string.broken_clouds; break;
+            case SHOWER_RAIN: id = R.string.shower_rain; break;
+            case RAIN: id = R.string.rain; break;
+            case THUNDERSTORM: id = R.string.thunderstorm; break;
+            case SNOW: id = R.string.snow; break;
+            case MIST: id = R.string.mist; break;
+            default: id = R.string.clear_sky; break;
+        }
+        return currentActivity.getResources().getString(id);
+    }
+
+    private static String getWeatherIconURL(WeatherType type) {
+        String link = "http://openweathermap.org/img/wn/<code>@2x.png";
+        switch (type) {
+            case FEW_CLOUDS: link = link.replace("<code>", "02d"); break;
+            case SCATTERED_CLOUDS: link = link.replace("<code>", "03d"); break;
+            case BROKEN_CLOUDS: link = link.replace("<code>", "04d"); break;
+            case SHOWER_RAIN: link = link.replace("<code>", "09d"); break;
+            case RAIN: link = link.replace("<code>", "10d"); break;
+            case THUNDERSTORM: link = link.replace("<code>", "11d"); break;
+            case SNOW: link = link.replace("<code>", "13d"); break;
+            case MIST: link = link.replace("<code>", "50d"); break;
+            default: link = link.replace("<code>", "01d"); break;
+        }
+        return link;
+    }
+
+    private static String api_key = "10266719b995c965d1b45db201ae8a90";
+    private static boolean hasRequestedPermissions = false;
+    transient private static Activity currentActivity = null;
+    transient private static Date last_update = null;
+    transient private static MeteoInfo last_infos = null;
+    transient private static FusedLocationProviderClient fusedLocationClient;
+
+    private static final List<Callback> resolve_callbacks = new ArrayList<>();
+    private static final List<Callback> reject_callbacks = new ArrayList<>();
+
+    private static double K2C(double x) {
+        return x - 273.15d;
+    }
+
+    private static JSONObject readStream(InputStream in) {
+        StringBuilder sb = new StringBuilder();
+        BufferedReader r = new BufferedReader(new InputStreamReader(in), 1024);
+        JSONObject res = null;
+        try {
+            String l = "";
+            while (l != null) {
+                l = r.readLine();
+                sb.append(l);
+            }
+            in.close();
+            res = new JSONObject(sb.toString());
+        } catch (Exception e) {}
+        return res;
+    }
+
+    private static void get_position(Callback onResolve, Callback onReject) {
+        boolean hasPerm = currentActivity.getPackageManager().checkPermission(
+                Manifest.permission.ACCESS_COARSE_LOCATION,
+                BuildingManager.getContext().getPackageName()
+        ) == PackageManager.PERMISSION_GRANTED;
+
+        if (!hasPerm) {
+            if (!hasRequestedPermissions) {
+                ActivityCompat.requestPermissions(
+                        currentActivity,
+                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
+                        926
+                );
+                hasRequestedPermissions = true;
+            } else {
+                onReject.call("No GPS permission");
+            }
+            return;
+        }
+
+        if (fusedLocationClient == null)
+            fusedLocationClient = new FusedLocationProviderClient(currentActivity);
+
+        try {
+            fusedLocationClient.getLastLocation().addOnSuccessListener(location -> {
+                if (location != null) {
+                    onResolve.call(new Position(location));
+                } else {
+                    onReject.call("\nLocation is null");
+                }
+            });
+        } catch (SecurityException e) {
+            onReject.call(e.getMessage());
+        }
+    }
+
+    private static void call_api(Position pos, Callback onResolve, Callback onReject) {
+        String link = "https://api.openweathermap.org/data/2.5/weather?lat="+ pos.getLatitude() +"&lon="+ pos.getLongitude() +"&appid="+ api_key;
+
+        ExecutorService service = Executors.newSingleThreadExecutor();
+        service.execute(() -> {
+            InputStream is;
+            try {
+                URL url = new URL(link);
+                is = url.openStream();
+            } catch (Exception e) {
+                onReject.call("\nCannot call API:\n" + e.getMessage());
+                return;
+            }
+
+            JSONObject res = readStream(is);
+            if (res == null) {
+                onReject.call("\nError while reading api data stream");
+            } else {
+                onResolve.call(res);
+            }
+        });
+    }
+
+    private static void process_meteo_data(JSONObject data, Callback onResolve, Callback onReject) {
+        try {
+            String weatherType = data.getJSONArray("weather").getJSONObject(0).getString("main");
+            data = data.getJSONObject("main");
+            double temp = K2C( data.getDouble("temp") );
+            double pressure = data.getDouble("pressure") / 1000.0d;
+            double humidity = data.getDouble("humidity");
+
+            MeteoInfo info = new MeteoInfo(WeatherFromString(weatherType), (float) temp, (float)humidity, (float)pressure);
+            onResolve.call(info);
+
+        } catch (Exception e) {
+            onReject.call("\nCannot parse data:\n" + e.getMessage());
+        }
+
+        resolve_callbacks.clear();
+        reject_callbacks.clear();
+    }
+
+    private static void retreive_meteo() {
+        Log.i("furwaz:debug", "Retreiving meteo data");
+        get_position(position -> {
+            Log.i("furwaz:debug", "Position - Resolve");
+            call_api((Position) position, data -> {
+                Log.i("furwaz:debug", "API - Resolve");
+                process_meteo_data((JSONObject) data, info -> {
+                    Log.i("furwaz:debug", "Data - Resolve (size = "+resolve_callbacks.size()+")");
+                    last_infos = (MeteoInfo) info;
+                    last_update = new Date();
+
+                    for (Callback c : resolve_callbacks) c.call(info);
+                    resolve_callbacks.clear();
+                    reject_callbacks.clear();
+                    return null;
+                }, e -> {
+                    Log.i("furwaz:debug", "Data - Reject");
+                    for (Callback c : reject_callbacks) c.call(e);
+                    resolve_callbacks.clear();
+                    reject_callbacks.clear();
+                    return null;
+                });
+                return null;
+            }, err -> {
+                Log.i("furwaz:debug", "API - Reject");
+                for (Callback c : reject_callbacks)
+                    c.call("API Error: data is null");
+
+                resolve_callbacks.clear();
+                reject_callbacks.clear();
+                return null;
+            });
+            return null;
+        }, reject -> {
+            Log.i("furwaz:debug", "Position - Reject");
+            for (Callback c : reject_callbacks)
+                c.call("\nCannot get location:\n" + reject);
+
+            resolve_callbacks.clear();
+            reject_callbacks.clear();
+            return null;
+        });
+    }
+
+    public static void SetCurrentActivity(Activity activity) {
+        currentActivity = activity;
+    }
+
+    public static void SetPermissionResult(boolean res) {
+        retreive_meteo();
+    }
+
+    public static void GetCurrentMeteo(Activity activity, Callback onResolve, Callback onReject) {
+        SetCurrentActivity(activity);
+        Date now = new Date();
+        if (last_update != null && (now.getTime() - last_update.getTime()) < 60000) { // update toutes les 1 minutes
+            if (last_infos != null) {
+                onResolve.call(last_infos);
+            } else {
+                onReject.call("Last infos is null");
+            }
+            return;
+        }
+
+        resolve_callbacks.add(onResolve);
+        reject_callbacks.add(onReject);
+        retreive_meteo();
     }
 
     float temperature = 0f;
     float humidity = 0f;
     float pressure = 1000f;
+    transient Bitmap icon = null;
+    WeatherType weather = WeatherType.CLEAR_SKY;
 
     public MeteoInfo() {
 
     }
 
-    public MeteoInfo(float temp, float humi, float pres) {
+    public MeteoInfo(WeatherType weather, float temp, float humi, float pres) {
+        this.weather = weather;
         this.temperature = temp;
         this.humidity = humi;
         this.pressure = pres;
@@ -34,6 +295,25 @@ public class MeteoInfo implements Serializable {
         return pressure;
     }
 
+    public WeatherType getWeather() {
+        return weather;
+    }
+
+    public String getWeatherIconURL() {
+        return getWeatherIconURL(weather);
+    }
+
+    public void getWeatherIcon(Callback onResolve, Callback onReject) {
+        if (icon != null) {
+            onResolve.call(icon);
+            return;
+        }
+        ImageManager.bitmapFromURL(image -> {
+            icon = (Bitmap) image;
+            return onResolve.call(image);
+        }, onReject, this.getWeatherIconURL());
+    }
+
     public void setTemperature(float temperature) {
         this.temperature = temperature;
     }
@@ -45,4 +325,8 @@ public class MeteoInfo implements Serializable {
     public void setPressure(float pressure) {
         this.pressure = pressure;
     }
+
+    public void setWeather(WeatherType weather) {
+        this.weather = weather;
+    }
 }
diff --git a/Sources/app/src/main/java/Structures/PhotoInfo.java b/Sources/app/src/main/java/Structures/PhotoInfo.java
index 9aa41f6f8de0a50a921267dd32ebd6ee8fcc4fb5..27f9bafc177da3a9483579b3c82321580fcf0c9a 100644
--- a/Sources/app/src/main/java/Structures/PhotoInfo.java
+++ b/Sources/app/src/main/java/Structures/PhotoInfo.java
@@ -3,6 +3,7 @@ package Structures;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
+import android.widget.Toast;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -28,7 +29,6 @@ public class PhotoInfo implements Serializable {
     protected void setPicture(byte[] im) {
         this.image = im;
         this.date = new Date();
-        this.meteo = MeteoInfo.GetCurrentMeteo();
     }
 
     public PhotoInfo() {
diff --git a/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java
index 3d5db8a05bd8fb341707fa2f08be008a1c9ce942..980c8ca35550007118dadb5e0b916d191543d62d 100644
--- a/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java
+++ b/Sources/app/src/main/java/com/furwaz/roomview/MainActivity.java
@@ -46,7 +46,6 @@ public class MainActivity extends AppCompatActivity {
         setContentView(R.layout.activity_main);
 
         BuildingManager.setContext(getBaseContext());
-        ImageManager.setContext(getBaseContext());
 
         ListView building_lv = findViewById(R.id.building_list);
         LinearLayout noDataLayout = findViewById(R.id.no_building_layout);
diff --git a/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java b/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java
index 7f0cbca3cf1ea88460daaaf7bdcaea552aba81a2..669ffa55d6706350503e14b8fd31e6156ae85243 100644
--- a/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java
+++ b/Sources/app/src/main/java/com/furwaz/roomview/PhotoActivity.java
@@ -8,8 +8,10 @@ import androidx.core.content.ContextCompat;
 
 import android.Manifest;
 import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
 import android.hardware.Camera;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
@@ -37,6 +39,7 @@ import Common.Callback;
 import Common.ImageManager;
 import Popups.WalkPopup;
 import Structures.BuildingInfo;
+import Structures.MeteoInfo;
 import Structures.Orientation;
 import Structures.PhotoInfo;
 import Structures.RoomInfo;
@@ -64,10 +67,12 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
     RoomInfo room = null;
     ZoneInfo zone = null;
     PhotoInfo photo = null;
+    MeteoInfo currentMeteo = null;
 
     Orientation displayed_orient = Orientation.NORTH;
     LinearLayout orient_layout = null;
 
+    @SuppressLint("SourceLockedOrientationActivity")
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -110,6 +115,7 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
         }
     }
 
+    @SuppressLint("SetTextI18n")
     protected void setupPhotoMode() {
         if (!checkCameraHardware()) {
             Toast.makeText(this, "Error : no camera detected on this device", Toast.LENGTH_SHORT).show();
@@ -132,6 +138,9 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
             btn_foto.setOnClickListener(view -> {
                 camera.takePicture(null, null, (bytes, cam) -> {
                     photo.setImage(bytes);
+                    if (currentMeteo != null) {
+                        photo.setMeteo(currentMeteo);
+                    }
                     setViewMode(MODE_EDIT);
                 });
             });
@@ -150,6 +159,34 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
             magnet = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
             register();
         }
+
+        MeteoInfo.GetCurrentMeteo(this, meteo -> {
+            currentMeteo = (MeteoInfo) meteo;
+            runOnUiThread(() -> {
+                ((TextView) findViewById(R.id.temperature)).setText(Math.round(currentMeteo.getTemperature()) + "°C");
+                ((TextView) findViewById(R.id.humidity)).setText((int)currentMeteo.getHumidity() + "%");
+            });
+            currentMeteo.getWeatherIcon(icon -> {
+                runOnUiThread(() -> {
+                    ImageView weather_icon = findViewById(R.id.weather_icon);
+                    weather_icon.setImageBitmap((Bitmap) icon);
+                });
+                return null;
+            }, error -> {
+                runOnUiThread(() -> {
+                    Toast.makeText(this, getResources().getString(R.string.error)+" : "+error, Toast.LENGTH_SHORT).show();
+                    ((TextView) findViewById(R.id.humidity)).setText(R.string.error);
+                });
+                return null;
+            });
+            return null;
+        }, error -> {
+            runOnUiThread(() -> {
+                Toast.makeText(this, getResources().getString(R.string.error)+" : "+error, Toast.LENGTH_SHORT).show();
+                ((TextView) findViewById(R.id.humidity)).setText(R.string.error);
+            });
+            return null;
+        });
     }
 
     protected void setupEditMode() {
@@ -258,7 +295,12 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
         if (sensorEvent.sensor == magnet) {
             magnetValues = sensorEvent.values;
             float[] res = new float[9];
-            SensorManager.getRotationMatrix(res, null, accelValues, magnetValues);
+            SensorManager.getRotationMatrix(
+                    res,
+                    null,
+                    new float[]{accelValues[0], -accelValues[2], accelValues[1]},
+                    new float[]{magnetValues[0], -magnetValues[2], magnetValues[1]}
+            );
             float[] values = new float[3];
             SensorManager.getOrientation(res, values);
             int angle = ((int)(values[0] * 180 / Math.PI) + 135) % 360;
@@ -294,20 +336,21 @@ public class PhotoActivity extends AppCompatActivity implements SensorEventListe
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
-        if (requestCode != 621) return;
-        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-            getCamera(_on_resolve_callback, _on_reject_callback);
-        } else {
-            if (_on_reject_callback != null) _on_reject_callback.call( getResources().getString(R.string.camera_error) );
+        switch (requestCode) {
+            case 621:
+                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                    getCamera(_on_resolve_callback, _on_reject_callback);
+                } else {
+                    if (_on_reject_callback != null) _on_reject_callback.call( getResources().getString(R.string.camera_error) );
+                }
+                break;
+            case 926:
+                MeteoInfo.SetPermissionResult(grantResults[0] == PackageManager.PERMISSION_GRANTED);
         }
     }
 
     private boolean checkCameraHardware() {
-        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)){
-            return true;
-        } else {
-            return false;
-        }
+        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
     }
 
     protected void showAddWalkPopup() {
diff --git a/Sources/app/src/main/res/drawable/ic_baseline_cloud_24.xml b/Sources/app/src/main/res/drawable/ic_baseline_cloud_24.xml
new file mode 100644
index 0000000000000000000000000000000000000000..235c7abc23bedaaa12646643ab1a9de93ed86814
--- /dev/null
+++ b/Sources/app/src/main/res/drawable/ic_baseline_cloud_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="@color/slate_700"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96z"/>
+</vector>
diff --git a/Sources/app/src/main/res/layout/activity_photo.xml b/Sources/app/src/main/res/layout/activity_photo.xml
index db9260b5a1d727bca382d47916fbba4dea3e079f..bf4d83cf8fa70214cfd6db6dcdacb4224c05b4a8 100644
--- a/Sources/app/src/main/res/layout/activity_photo.xml
+++ b/Sources/app/src/main/res/layout/activity_photo.xml
@@ -149,6 +149,7 @@
                     android:layout_weight="1"
                     android:layout_height="wrap_content"
                     android:orientation="horizontal"
+                    android:layout_gravity="center"
                     android:gravity="center"
                     android:padding="6dp">
 
@@ -167,6 +168,7 @@
                     android:layout_weight="1"
                     android:layout_height="wrap_content"
                     android:orientation="horizontal"
+                    android:layout_gravity="center"
                     android:gravity="center">
 
                     <ImageButton
@@ -183,7 +185,27 @@
                     android:layout_width="0dp"
                     android:layout_weight="1"
                     android:layout_height="wrap_content"
-                    android:orientation="horizontal" />
+                    android:layout_gravity="center"
+                    android:gravity="center"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:id="@+id/temperature"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        />
+                    <TextView
+                        android:id="@+id/humidity"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/loading"
+                        />
+                    <ImageView
+                        android:id="@+id/weather_icon"
+                        android:layout_width="50dp"
+                        android:layout_height="50dp"
+                        android:src="@drawable/ic_baseline_cloud_24" />
+                </LinearLayout>
             </LinearLayout>
         </LinearLayout>
     </LinearLayout>
diff --git a/Sources/app/src/main/res/layout/photo_info_popup.xml b/Sources/app/src/main/res/layout/photo_info_popup.xml
index 5f2bd20244f0f4c0f07399b6994cdcd43abb71f8..190882691564b6509e6a6c09b7a54b0354548d6e 100644
--- a/Sources/app/src/main/res/layout/photo_info_popup.xml
+++ b/Sources/app/src/main/res/layout/photo_info_popup.xml
@@ -14,8 +14,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:background="@color/blue_500"
-            android:layout_marginBottom="20dp">
+            android:background="@color/blue_500">
 
             <TextView
                 android:id="@+id/info_title"
@@ -31,6 +30,36 @@
                 />
         </LinearLayout>
 
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginTop="20dp">
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="4dp"
+                android:layout_gravity="center"
+                android:background="@color/slate_200"/>
+            <TextView
+                android:layout_width="0dp"
+                android:layout_weight="2"
+                android:layout_height="wrap_content"
+                android:text="@string/informations"
+                android:textAlignment="center"
+                android:textStyle="bold"
+                android:textColor="@color/slate_300"
+                android:textSize="16sp"
+                android:layout_marginStart="4dp"
+                android:layout_marginEnd="4dp"/>
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="4dp"
+                android:layout_gravity="center"
+                android:background="@color/slate_200"/>
+        </LinearLayout>
+
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -81,6 +110,136 @@
                 android:layout_marginEnd="8sp"/>
         </LinearLayout>
 
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginTop="20dp">
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="4dp"
+                android:layout_gravity="center"
+                android:background="@color/slate_200"/>
+            <TextView
+                android:layout_width="0dp"
+                android:layout_weight="2"
+                android:layout_height="wrap_content"
+                android:text="@string/meteo"
+                android:textAlignment="center"
+                android:textStyle="bold"
+                android:textColor="@color/slate_300"
+                android:textSize="16sp"
+                android:layout_marginStart="4dp"
+                android:layout_marginEnd="4dp"/>
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="4dp"
+                android:layout_gravity="center"
+                android:background="@color/slate_200"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/temperature"
+                android:textStyle="bold"
+                android:textColor="@color/slate_600"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+            <TextView
+                android:id="@+id/photo_temp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text=""
+                android:textStyle="normal"
+                android:textColor="@color/blue_500"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/humidity"
+                android:textStyle="bold"
+                android:textColor="@color/slate_600"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+            <TextView
+                android:id="@+id/photo_humidity"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text=""
+                android:textStyle="normal"
+                android:textColor="@color/blue_500"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/pressure"
+                android:textStyle="bold"
+                android:textColor="@color/slate_600"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+            <TextView
+                android:id="@+id/photo_pressure"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text=""
+                android:textStyle="normal"
+                android:textColor="@color/blue_500"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/weather"
+                android:textStyle="bold"
+                android:textColor="@color/slate_600"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+            <TextView
+                android:layout_width="match_parent"
+                android:id="@+id/photo_weather"
+                android:layout_height="wrap_content"
+                android:text=""
+                android:textStyle="normal"
+                android:textColor="@color/blue_500"
+                android:textSize="16sp"
+                android:layout_marginStart="8sp"
+                android:layout_marginEnd="8sp"/>
+        </LinearLayout>
+
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/Sources/app/src/main/res/values-fr/strings.xml b/Sources/app/src/main/res/values-fr/strings.xml
index 18571299173bc15b8924e316256b98506523cf17..ec092b155ab3c2f5505fe00493cc97efa60a2a0e 100644
--- a/Sources/app/src/main/res/values-fr/strings.xml
+++ b/Sources/app/src/main/res/values-fr/strings.xml
@@ -103,4 +103,21 @@
     <string name="stair">Escalier</string>
     <string name="not_defined">Vous ne pouvez pas aller là. Ce chemin n\'est pas encore défini.</string>
     <string name="no_photo_yet">Vous ne pouvez pas aller là. Cette pièce n\'a pas encore de zone.</string>
+    <string name="loading">Chargement ...</string>
+    <string name="error">Erreur</string>
+    <string name="informations">Informations</string>
+    <string name="meteo">Météo</string>
+    <string name="temperature">Température</string>
+    <string name="humidity">Humidité</string>
+    <string name="pressure">Pression</string>
+    <string name="weather">Météo</string>
+    <string name="few_clouds">Peu nuageux</string>
+    <string name="scattered_clouds">Nuageux</string>
+    <string name="broken_clouds">Très nuageux</string>
+    <string name="shower_rain">Très Pluvieux</string>
+    <string name="rain">Pluvieux</string>
+    <string name="thunderstorm">Orageux</string>
+    <string name="snow">Enneigé</string>
+    <string name="mist">Brumeux</string>
+    <string name="clear_sky">Ciel dégagé</string>
 </resources>
\ No newline at end of file
diff --git a/Sources/app/src/main/res/values/strings.xml b/Sources/app/src/main/res/values/strings.xml
index 0c5a90b25bf1a5f7a9273a52cd85408c8c90547d..20681026dcec26a64bcb9523dd888bf3834fa33a 100644
--- a/Sources/app/src/main/res/values/strings.xml
+++ b/Sources/app/src/main/res/values/strings.xml
@@ -103,4 +103,21 @@
     <string name="stair">Stair</string>
     <string name="not_defined">You can\'t go here. This pathway is not defined yet.</string>
     <string name="no_photo_yet">You can\'t go here. This room doesn\'t have any zone.</string>
+    <string name="loading">Loading ...</string>
+    <string name="error">Error</string>
+    <string name="informations">Informations</string>
+    <string name="meteo">Meteo</string>
+    <string name="temperature">Temperature</string>
+    <string name="humidity">Humidity</string>
+    <string name="pressure">Pressure</string>
+    <string name="weather">Weather</string>
+    <string name="few_clouds">A little bit cloudy</string>
+    <string name="scattered_clouds">Cloudy</string>
+    <string name="broken_clouds">Very cloudy</string>
+    <string name="shower_rain">Very Raining</string>
+    <string name="rain">Raining</string>
+    <string name="thunderstorm">Stormy</string>
+    <string name="snow">Snowy</string>
+    <string name="mist">Foggy</string>
+    <string name="clear_sky">Clear</string>
 </resources>
\ No newline at end of file