diff --git a/Dockerfile b/Dockerfile
index ad00d2f..29ccc0c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,4 +20,4 @@ RUN pip install -r requirements.txt
# Copy the application source code.
COPY . .
-CMD ["taipy", "run", "--no-debug", "--no-reloader", "receiver.py", "-H", "0.0.0.0", "-P", "5000"]
+CMD ["taipy", "run", "--no-debug", "--no-reloader", "main.py", "-H", "0.0.0.0", "-P", "5000"]
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..584bf8c
--- /dev/null
+++ b/main.py
@@ -0,0 +1,190 @@
+import math
+import time
+from taipy import Gui
+from taipy.gui import invoke_long_callback
+import numpy as np
+import pandas as pd
+
+init_lat = 49.247
+init_long = 1.377
+
+factory_lat = 49.246
+factory_long = 1.369
+
+diff_lat = abs(init_lat - factory_lat) * 15
+diff_long = abs(init_long - factory_long) * 15
+
+lats_unique = np.arange(init_lat - diff_lat, init_lat + diff_lat, 0.001)
+longs_unique = np.arange(init_long - diff_long, init_long + diff_long, 0.001)
+
+countdown = 20
+periods = 0
+line_data = pd.DataFrame({"Time": [], "Max AQI": []})
+
+drone_data = pd.DataFrame(
+ {
+ "Drone ID": [43, 234, 32, 23, 5, 323, 12, 238, 21, 84],
+ "Battery Level": [
+ "86%",
+ "56%",
+ "45%",
+ "12%",
+ "85%",
+ "67%",
+ "34%",
+ "78%",
+ "90%",
+ "100%",
+ ],
+ "AQI": [40, 34, 24, 22, 33, 45, 23, 34, 23, 34],
+ "Status": [
+ "Moving",
+ "Measuring",
+ "Measuring",
+ "Stopped",
+ "Measuring",
+ "Moving",
+ "Moving",
+ "Measuring",
+ "Measuring",
+ "Measuring",
+ ],
+ }
+)
+
+
+def pollution(lat: float, long: float):
+ """
+ Return pollution level in percentage
+ Pollution should be centered around the factory
+ Pollution should decrease with distance to factory
+ Pollution should have an added random component
+
+ Args:
+ - lat: latitude
+ - long: longitude
+
+ Returns:
+ - pollution level
+ """
+ global countdown
+ return 80 * (0.5 + 0.5 * math.sin(countdown / 20)) * math.exp(
+ -(0.8 * (lat - factory_lat) ** 2 + 0.2 * (long - factory_long) ** 2) / 0.00005
+ ) + np.random.randint(0, 50)
+
+
+layout_map = {
+ "mapbox": {
+ "style": "open-street-map",
+ "center": {"lat": init_lat, "lon": init_long},
+ "zoom": 13,
+ },
+ "dragmode": "false",
+ "margin": {"l": 0, "r": 0, "b": 0, "t": 0},
+}
+
+layout_line = {
+ "title": "Max Measured AQI over Time",
+ "yaxis": {"range": [0, 150]},
+}
+
+lats = []
+longs = []
+pollutions = []
+times = []
+max_pollutions = []
+
+for lat in lats_unique:
+ for long in longs_unique:
+ lats.append(lat)
+ longs.append(long)
+ pollutions.append(pollution(lat, long))
+
+
+def iddle():
+ """
+ Only call an update every 3 seconds
+ """
+ global countdown
+ while True:
+ time.sleep(3)
+ countdown += 5
+
+
+def on_init(state):
+ """
+ Start the update loop
+ """
+ invoke_long_callback(state, iddle, [], update, [], 2000)
+
+
+def update(state):
+ """
+ Update the pollution levels
+ """
+ for i in range(len(pollutions)):
+ pollutions[i] = pollution(lats[i], longs[i])
+ state.data_province_displayed = pd.DataFrame(
+ {
+ "Latitude": lats,
+ "Longitude": longs,
+ "Pollution": pollutions,
+ }
+ )
+ state.pollutions = pollutions
+ # Add an hour to the time
+ state.periods = state.periods + 1
+ state.max_pollutions = state.max_pollutions + [max(pollutions)]
+ state.times = pd.date_range(
+ "2020-11-04", periods=len(state.max_pollutions), freq="H"
+ )
+ state.line_data = pd.DataFrame(
+ {
+ "Time": state.times,
+ "Max AQI": state.max_pollutions,
+ }
+ )
+
+
+data_province_displayed = pd.DataFrame(
+ {
+ "Latitude": lats,
+ "Longitude": longs,
+ "Pollution": pollutions,
+ }
+)
+
+options = {
+ "opacity": 0.8,
+ "colorscale": "Bluered",
+ "zmin": 0,
+ "zmax": 140,
+ "colorbar": {"title": "AQI"},
+ "hoverinfo": "none",
+}
+config = {"scrollZoom": False, "displayModeBar": False}
+
+max_pollution = data_province_displayed["Pollution"].max()
+
+page = """
+<|{data_province_displayed}|chart|type=densitymapbox|plot_config={config}|options={options}|lat=Latitude|lon=Longitude|layout={layout_map}|z=Pollution|mode=markers|class_name=map|height=40vh|>
+<|layout|columns=1 2 2|
+<|part|class_name=card|
+**Max Measured AQI:**
+<|{int(data_province_displayed["Pollution"].max())}|indicator|value={int(data_province_displayed["Pollution"].max())}|min=140|max=0|>
+
+**Average Measured AQI:**
+<|{int(data_province_displayed["Pollution"].mean())}|indicator|value={int(data_province_displayed["Pollution"].mean())}|min=140|max=0|>
+|>
+
+<|part|class_name=card|
+<|{drone_data}|table|show_all=True|>
+|>
+
+<|part|class_name=card|
+<|{line_data[-30:]}|chart|type=lines|x=Time|y=Max AQI|layout={layout_line}|height=40vh|>
+|>
+|>
+"""
+
+Gui(page).run(use_reloader=True)