diff --git a/aruco_tags.json b/aruco_tags.json
new file mode 100644
index 0000000000000000000000000000000000000000..d83d93e96459e7286ab610a4c7b2607195fba63e
--- /dev/null
+++ b/aruco_tags.json
@@ -0,0 +1 @@
+{"arucos": []}
\ No newline at end of file
diff --git a/demo.py b/demo.py
index ff3e7cd96eb7ec47769091ab25295062fac0c1f7..0829b33e888570b123f05714cbb50fae7c47afc3 100644
--- a/demo.py
+++ b/demo.py
@@ -1,5 +1,5 @@
-# from ar_sandbox import Sandbox
-# from ar_sandbox.wrapper import sandbox_wrapper as sw
+import falcon
+from ar_sandbox import Sandbox
 import sys
 import cv2
 import numpy as np
@@ -9,17 +9,15 @@ from PIL import Image
 import requests
 import time
 import math
-
+import json
 
 NORMALIZATION_BETWEEN = (0.8, 1.2)
 LO_NORM = NORMALIZATION_BETWEEN[0]
 HI_NORM = NORMALIZATION_BETWEEN[1]
-
 SHOW_LINES = True
 USE_HARD_COLORS = False
 LINE_COLORS = [255, 255, 255]
 
-
 COLORS_FULL_SPECTRUM_SOFT = [
     (0.2, (0, 0, 255)),
     (.25, (0, 255, 255)),
@@ -66,7 +64,6 @@ COLOR_B_HARD = [c[1][2] for c in COLORS_FULL_SPECTRUM_HARD]
 COLORMAP = None
 COLORMAP_HARD = None
 
-DEFAULT_URL = "http://localhost:8000"
 
 
 def try_and_ignore(ignore=Exception, default_value=0.0):
@@ -87,6 +84,9 @@ def try_and_ignore(ignore=Exception, default_value=0.0):
 parse_int = try_and_ignore(ValueError, 0)(int)
 parse_float = try_and_ignore(ValueError, 0.0)(float)
 
+api_content_esri = ""
+api_content_aruco = ""
+
 
 class FakeSandbox:
     """Placeholder for testing purposes"""
@@ -100,19 +100,16 @@ class FakeSandbox:
     def start(self, *args):
         cap = cv2.VideoCapture(0)
         while cap.isOpened():
-            # im = Image.open("test_aru.png")
             ret, fr = cap.read()
             frame = cv2.resize(fr, (588, 432))
             mat = np.loadtxt("depth")
 
-            # mat = cv2.cvtColor(fr, cv2.COLOR_BGR2GRAY)
             mat2 = frame
             if self.on_frame is not None:
                 frame = self.on_frame(mat, mat2)
 
             cv2.imshow("frame", frame)
 
-            # time.sleep(self.refresh // 1000)
             k = cv2.waitKey(self.refresh)
             if k == 27:
                 break
@@ -131,16 +128,7 @@ def get_color(depth, hard_colors=False) -> np.ndarray:
         A 3 channel BGR matrix of the same size as depth_matrix.
     """
     depth_matrix = depth.copy()
-    # if hard_colors:
-    #     pts = POINTS_HARD
-    #     r = COLOR_R_HARD
-    #     g = COLOR_G_HARD
-    #     b = COLOR_B_HARD
-    # else:
-    #     pts = POINTS
-    #     r = COLOR_R
-    #     g = COLOR_G
-    #     b = COLOR_B
+
     if hard_colors:
         pts = COLORMAP_HARD[0]
         r = COLORMAP_HARD[1]
@@ -153,11 +141,8 @@ def get_color(depth, hard_colors=False) -> np.ndarray:
         b = COLORMAP[3]
 
     r_val = np.interp(depth_matrix, pts, r)
-    # print(r_val)
     g_val = np.interp(depth_matrix, pts, g)
-    # print(g_val)
     b_val = np.interp(depth_matrix, pts, b)
-    # print(b_val)
     res = np.dstack((b_val, g_val, r_val)).astype(np.uint8)
     return res
 
@@ -178,6 +163,7 @@ def send_request(body, url="http://localhost:8000/map"):
         print(e)
 
 
+# This is the older method that was used to transmit arucos over the network
 def build_req_body(map, tag_list):
     arucos = []
     for t in tag_list:
@@ -201,6 +187,29 @@ def build_req_body(map, tag_list):
     return body
 
 
+# This new method is basically a copy pasted version of the one above without the map
+# Maybe both of them are not needed anymore
+def build_arucos_json(tag_list):
+    arucos = []
+    for t in tag_list:
+        print(t)
+        (x, y), id, r = t
+        (x, y) = (parse_int(x), parse_int(y))
+        id = parse_int(id)
+        r = parse_float(r)
+        arucos.append({
+            "tag_id": id,
+            "position": {
+                "x": x,
+                "y": y
+            },
+            "rotation": r
+        })
+    body = {
+        "arucos": arucos
+    }
+    return body
+
 def normalize_array(array):
     return (array - array.min())/(array.max() - array.min())
 
@@ -216,6 +225,7 @@ def normalize_array_between(array, lower_bound, higher_bound):
 
 
 def make_esri_and_send(depth, color, *args):
+    global api_content_esri, api_content_aruco
     if COLORMAP is None or COLORMAP_HARD is None:
         gen_global_default_cmaps()
     # Normalization step
@@ -241,16 +251,30 @@ def make_esri_and_send(depth, color, *args):
 
     # Aruco detection
     grayscale_frame = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
-    _, (corn, ids, rej), centers, rots = detect_aruco(grayscale_frame)
+    
+    _, (corn, ids, rej), centers, rots = detect_aruco(grayscale_frame) #TODO
 
     # Create map and tag dictionary
     esri_map = EsriAscii.from_ndarray(depth)
-    detected = build_tag_list(ids, centers, rots)
+    detected = build_tag_list(ids, centers, rots) #TODO
 
     # Send it toward api
-    send_request(build_req_body(esri_map, detected), url=DEFAULT_URL)
-    # May locally save the esri_map
-    # esri_map.to_file("depth_map_v2.asc")
+    #send_request(build_req_body(esri_map, detected), url=DEFAULT_URL)
+    #TODO
+    #send_request(build_req_body(esri_map, detected), url=dest)
+    #send_request(build_req_body(esri_map, []), url=dest)
+    #send_request(build_req_body(esri_map, detected), url=DEFAULT_URL2)
+
+    
+    # May locally save the esri_map & arucos
+    # esri_map.to_file("depth_map.asc")
+    api_content_esri = esri_map.to_ascii()
+    api_content_aruco = build_arucos_json(detected)
+    # tags = build_arucos_json(detected)
+
+    # with open("aruco_tags.json", "w") as fp:
+    #     json.dump(tags, fp)
+
     # Return value will be displayed on the beamer
     return levels
 
@@ -266,12 +290,17 @@ def get_center(corner):
     c0, _, c2, _ = corner[0]
     return int(c0[0] + (c2[0]-c0[0]) // 2), int(c0[1] + (c2[1]-c0[1]) // 2)
 
+# TODO def detect_aruco(a, b=None, c=None): return
 
 def detect_aruco(frame,
-                 aruco_dict=cv2.aruco.Dictionary_get(cv2.aruco.DICT_4X4_50),
-                 aruco_params=cv2.aruco.DetectorParameters_create()):
-    output = frame.copy()
-    (corners, ids, rejected) = cv2.aruco.detectMarkers(frame, aruco_dict, parameters=aruco_params)
+                 aruco_dict=cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50),
+                 aruco_params=cv2.aruco.DetectorParameters()):
+    # output = frame.copy()
+    
+    #(corners, ids, rejected) = cv2.aruco.detectMarkers(frame, aruco_dict, parameters=aruco_params)
+    detector = cv2.aruco.ArucoDetector(aruco_dict, aruco_params)
+    (corners, ids, rejected) = detector.detectMarkers(frame)
+
     centers = []
     rotations = []
     for c in range(len(corners)):
@@ -279,14 +308,13 @@ def detect_aruco(frame,
             ctr = get_center(corners[c])
             top_left = corners[c][0][0]
             centers.append(get_center(corners[c]))
-            # print("Corner is", corners[c], "Center is", get_center(corners[c]))
             (w1, w2) = [-1, -1]
             (v1, v2) = top_left - ctr
             rotation_in_degree = math.degrees(math.atan2(w2 * v1 - w1 * v2, w1 * v1 + w2 * v2))
             rotations.append(round(rotation_in_degree, 2))
         except Exception as e:
             print(e)
-    return output, (corners, ids, rejected), centers, rotations
+    return None, (corners, ids, rejected), centers, rotations
 
 
 def save_matrices(depth, frame, *args):
@@ -335,18 +363,18 @@ def rgb_to_hex(rgb):
     return '#%02x%02x%02x' % rgb
 
 
-if __name__ == "__main__":
-    import argparse
-    parser = argparse.ArgumentParser()
-    parser.add_argument("-c", "--colors", default="")
-    parser.add_argument("-u", "--url", default=DEFAULT_URL)
-    parser.add_argument("-l", "--lines", action="store_true")
-    parser.add_argument("-H", "--hard", action="store_true")
-    arguments = parser.parse_args()
+class ApiEsri:
+    def on_get(self, req, resp):
+        resp.media = api_content_esri
+
+class ApiAruco:
+    def on_get(self, req, resp):
+        # resp.media = json.dumps(api_content_aruco)
+        resp.media = api_content_aruco
+
 
-    print(arguments)
-    DEFAULT_URL = arguments.url if arguments.url.startswith("http://") else "http://" + arguments.url
-    arg_colors = arguments.colors
+def main():
+    arg_colors = ""
     if arg_colors != "":
         colours = []
         cols = arg_colors.split(",")
@@ -361,22 +389,38 @@ if __name__ == "__main__":
         COLORMAP_HARD = create_colormap(create_hard_colors(cmap))
 
     SHOW_LINES = False
-    if arguments.lines:
-        SHOW_LINES = True
-
     USE_HARD_COLORS = False
-    if arguments.hard:
-        USE_HARD_COLORS = True
 
     # colours = [(.2, (0,0,128)), (.25, (68, 87, 227)), (.3, (236, 255, 89)),(.4, (67, 138, 65)),(.6, (128,128,128)), (.8, (255, 255, 255))]
     # colours = [(.2, (128,0,0)),(.3, (255,0,0)),(.4, (255,255,255)), (.5, (0,0,255)), (.6,(0, 0, 128))]
     # COLORMAP = create_colormap(color_array=colours)
     # COLORMAP_HARD = create_colormap(create_hard_colors(colours))
 
-    # USE_HARD_COLORS=True
-
     LINE_COLORS = [0,0,0]
-    box = FakeSandbox(refresh=1000)
+    box = Sandbox(refresh=1000)
+    box.verbosity = 5
     box.init()
     box.on_frame = make_esri_and_send
     box.start(box)
+
+# ---- MAIN ----
+
+from wsgiref.simple_server import make_server
+from threading import Thread
+
+app = falcon.App()
+app.add_route('/sandbox', ApiEsri())
+app.add_route('/aruco', ApiAruco())
+
+class ApiThread(Thread):
+    def run(self):
+        print("run")
+        with make_server('', 8000, app) as httpd:
+            print('Serving on port 8000...')
+
+            # Serve until process is killed
+            httpd.serve_forever()
+
+
+ApiThread().start()
+main()
diff --git a/env.sh b/env.sh
index c58ef142030d2ead41f1f46f3b9cda323b7fc5c9..5cef6089bc5515a761151f95691a7fb24c690ae0 100644
--- a/env.sh
+++ b/env.sh
@@ -1 +1,2 @@
-export LD_LIBRARY_PATH=/home/alexis/sandbox/sandbox_docker-builder/build/lib/
+#export LD_LIBRARY_PATH=/home/alexis/sandbox/sandbox_docker-builder/build/lib/
+export LD_LIBRARY_PATH=/home/sandbox/Documents/ar_sandbox_lib/build
diff --git a/sandbox_conf.yaml b/sandbox_conf.yaml
index 9fa6ebd2d61e28205719b28168e50d0078888247..a59661043208415b2ddfe2ac04d13cd7c0494fa2 100644
--- a/sandbox_conf.yaml
+++ b/sandbox_conf.yaml
@@ -1,27 +1,35 @@
 AdjustingMatrix:
-  angle: 1.4119340386036046
+  #angle: 0.5119340386036046
+  angle: 0.5
   width: 3
   height: 2
-  matrix: [0.999696374, 0.0246404037, 0, -0.0246404037, 0.999696374, 0]
+  matrix: [1.0, 0, 50, -0, 1, 70]
+    #matrix: [1.0, 0, 50, -0, 1, 50]
+    # [?, rotation, ?, ?, ?, ?]
+    #angle: 0
+    #width: 3
+    #height: 2
+    #matrix: [1, 0, 0, -0, 1, 0]
 DistanceTopSandbox:
-  distance: 1
+  distance: 1.11300004
 CroppingMask:
   x: 52
   y: 19
-  width: 588 # 568
-  height: 432
+  width: 588
+  height: 437
 BeamerResolution:
-  width: 1400
-  height: 1050
+  width: 1280
+  height: 1024
 BeamerPosition:
-  x: 0.0536931753
-  y: 0.260815978
-  z: -0.325273067
+  x: -0.0419691354
+  #x: -0.0419691354
+  y: 0.238534391
+  z: -0.126809254
 FrameProcessProfil:
-  contrast: 1.0900000000000001
-  brightness: 14
-  minDistance: 15
-  cannyEdgeThreshold: 184
-  houghAccThreshold: 35
-  minRadius: 0
-  maxRadius: 0
+  contrast: 1.1200000000000001
+  brightness: -148
+  minDistance: 100
+  cannyEdgeThreshold: 86
+  houghAccThreshold: 44
+  minRadius: 2
+  maxRadius: 14
diff --git a/sandbox_conf_backup.yaml b/sandbox_conf_backup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4a32850888b9e5c1bd6451e6af0b746fc86de00d
--- /dev/null
+++ b/sandbox_conf_backup.yaml
@@ -0,0 +1,27 @@
+AdjustingMatrix:
+  angle: 1.4119340386036046
+  width: 3
+  height: 2
+  matrix: [0.999696374, 0.0246404037, 0, -0.0246404037, 0.999696374, 0]
+DistanceTopSandbox:
+  distance: 1
+CroppingMask:
+  x: 52
+  y: 19
+  width: 588 # 568
+  height: 432
+BeamerResolution:
+  width: 1280
+  height: 1024
+BeamerPosition:
+  x: 0.0536931753
+  y: 0.260815978
+  z: -0.325273067
+FrameProcessProfil:
+  contrast: 1.0900000000000001
+  brightness: 14
+  minDistance: 15
+  cannyEdgeThreshold: 184
+  houghAccThreshold: 35
+  minRadius: 0
+  maxRadius: 0