diff --git a/backend/.env.docker b/backend/.env.docker
index 0d29546427f65192b17bf57b36807d3ddf4a91f4..5f01a4967ee84ac8b8e19bfbf02e74b07026328c 100644
--- a/backend/.env.docker
+++ b/backend/.env.docker
@@ -2,7 +2,7 @@
 INFLUXDB_URL=http://influxdb2:8086
 INFLUXDB_ORG=docs
 INFLUXDB_BUCKET=co2-test
-INFLUXDB_TOKEN=w-Isk1D35T90Srj_auFTxsbksn1zRB5MiNZf6h6RuNdb9-2s9ie5c1488JqoYILKrceVm0LaE5KCN2dXdDM-jA==
+INFLUXDB_TOKEN=1xa5lLACRZDYsvinhABndZ8GGzBY7-gTQsAf309c0aTnPPtBxixPEEOPuXLmkTxUKy8golKae6fsrh1wD4SL0A==
 # MQTT config
 MQTT_BROKER_URL=mosquitto-broker
 MQTT_TOPIC="co2/#"
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
index f0116b851502d8f00214a4a059b50c186b3a3c62..9851bc8d2bb74ed633ff50bb53bcc55c073726c2 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -5,7 +5,7 @@ FROM python:latest
 WORKDIR /app
 
 # Kopiere Projektdateien für Abhängigkeitsmanagement
-COPY pyproject.toml uv.lock ./
+COPY . .
 
 # Installiere pip und uv
 RUN pip install --upgrade pip && \
@@ -21,7 +21,7 @@ RUN uv sync
 # für Admin oberfläche
 #RUN python manage.py createsuperuser
 
-COPY . .
+#COPY . .
 
 RUN .venv/bin/python manage.py migrate
 
diff --git a/backend/stream_processing/jsonhandler.py b/backend/stream_processing/jsonhandler.py
deleted file mode 100644
index d90ba36ca8d631e91f4e590796043555672eb0e4..0000000000000000000000000000000000000000
--- a/backend/stream_processing/jsonhandler.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import json
-import os
-
-def load_json(file_name: str) -> dict:
-    """
-    ladet eine JSON Datei, wenn diese existiert,
-    und gibt diese als dictionary zurück
-    key : value
-    """
-    if not os.path.exists(file_name):
-        return {}
-    with open(file_name) as f:
-        mac_room_mapping = json.load(f)
-    return mac_room_mapping
-
-def write_json(mac_room_mapping: dict, file_name: str):
-    """
-    Nimmt ein dictionary und schreibt dessen
-    Inhalte in eine JSON Datei
-    """
-    with open(file_name, "w") as f:
-        f.seek(0)
-        json.dump(mac_room_mapping, f, indent=4)
-        f.truncate()  # TODO Check if truncate is necessary?
diff --git a/backend/uv.lock b/backend/uv.lock
index 497e2a0364a7eb9b6725ea0e3435759d1f4de543..e9aa3ae9dd29eaa3106659a609e77d96abe5ea62 100644
--- a/backend/uv.lock
+++ b/backend/uv.lock
@@ -1,14 +1,14 @@
 version = 1
-revision = 1
+revision = 2
 requires-python = ">=3.12"
 
 [[package]]
 name = "asgiref"
 version = "3.8.1"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186 }
+sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186, upload-time = "2024-03-22T14:39:36.863Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 },
+    { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" },
 ]
 
 [[package]]
@@ -42,25 +42,25 @@ dev = [{ name = "ruff", specifier = ">=0.11.5" }]
 
 [[package]]
 name = "certifi"
-version = "2025.1.31"
+version = "2025.4.26"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
+    { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" },
 ]
 
 [[package]]
 name = "django"
-version = "5.2"
+version = "5.2.1"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "asgiref" },
     { name = "sqlparse" },
     { name = "tzdata", marker = "sys_platform == 'win32'" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/4c/1b/c6da718c65228eb3a7ff7ba6a32d8e80fa840ca9057490504e099e4dd1ef/Django-5.2.tar.gz", hash = "sha256:1a47f7a7a3d43ce64570d350e008d2949abe8c7e21737b351b6a1611277c6d89", size = 10824891 }
+sdist = { url = "https://files.pythonhosted.org/packages/ac/10/0d546258772b8f31398e67c85e52c66ebc2b13a647193c3eef8ee433f1a8/django-5.2.1.tar.gz", hash = "sha256:57fe1f1b59462caed092c80b3dd324fd92161b620d59a9ba9181c34746c97284", size = 10818735, upload-time = "2025-05-07T14:06:17.543Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/63/e0/6a5b5ea350c5bd63fe94b05e4c146c18facb51229d9dee42aa39f9fc2214/Django-5.2-py3-none-any.whl", hash = "sha256:91ceed4e3a6db5aedced65e3c8f963118ea9ba753fc620831c77074e620e7d83", size = 8301361 },
+    { url = "https://files.pythonhosted.org/packages/90/92/7448697b5838b3a1c6e1d2d6a673e908d0398e84dc4f803a2ce11e7ffc0f/django-5.2.1-py3-none-any.whl", hash = "sha256:a9b680e84f9a0e71da83e399f1e922e1ab37b2173ced046b541c72e1589a5961", size = 8301833, upload-time = "2025-05-07T14:06:10.955Z" },
 ]
 
 [[package]]
@@ -71,9 +71,9 @@ dependencies = [
     { name = "asgiref" },
     { name = "django" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/93/6c/16f6cb6064c63074fd5b2bd494eb319afd846236d9c1a6c765946df2c289/django_cors_headers-4.7.0.tar.gz", hash = "sha256:6fdf31bf9c6d6448ba09ef57157db2268d515d94fc5c89a0a1028e1fc03ee52b", size = 21037 }
+sdist = { url = "https://files.pythonhosted.org/packages/93/6c/16f6cb6064c63074fd5b2bd494eb319afd846236d9c1a6c765946df2c289/django_cors_headers-4.7.0.tar.gz", hash = "sha256:6fdf31bf9c6d6448ba09ef57157db2268d515d94fc5c89a0a1028e1fc03ee52b", size = 21037, upload-time = "2025-02-06T22:15:28.924Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/7e/a2/7bcfff86314bd9dd698180e31ba00604001606efb518a06cca6833a54285/django_cors_headers-4.7.0-py3-none-any.whl", hash = "sha256:f1c125dcd58479fe7a67fe2499c16ee38b81b397463cf025f0e2c42937421070", size = 12794 },
+    { url = "https://files.pythonhosted.org/packages/7e/a2/7bcfff86314bd9dd698180e31ba00604001606efb518a06cca6833a54285/django_cors_headers-4.7.0-py3-none-any.whl", hash = "sha256:f1c125dcd58479fe7a67fe2499c16ee38b81b397463cf025f0e2c42937421070", size = 12794, upload-time = "2025-02-06T22:15:24.341Z" },
 ]
 
 [[package]]
@@ -87,18 +87,18 @@ dependencies = [
     { name = "setuptools" },
     { name = "urllib3" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/11/47/b756380917cb4b968bd871fc006128e2cc9897fb1ab4bcf7d108f9601e78/influxdb_client-1.48.0.tar.gz", hash = "sha256:414d5b5eff7d2b6b453f33e2826ea9872ea04a11996ba9c8604b0c1df57c8559", size = 386415 }
+sdist = { url = "https://files.pythonhosted.org/packages/11/47/b756380917cb4b968bd871fc006128e2cc9897fb1ab4bcf7d108f9601e78/influxdb_client-1.48.0.tar.gz", hash = "sha256:414d5b5eff7d2b6b453f33e2826ea9872ea04a11996ba9c8604b0c1df57c8559", size = 386415, upload-time = "2024-11-27T08:26:32.909Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/5c/b3/1edc89584b8d1bc5226cf508b67ab64da3ba83041cab348861e6f4392326/influxdb_client-1.48.0-py3-none-any.whl", hash = "sha256:410db15db761df7ea98adb333c7a03f05bcc2ceef4830cefb7071b888be2b827", size = 746177 },
+    { url = "https://files.pythonhosted.org/packages/5c/b3/1edc89584b8d1bc5226cf508b67ab64da3ba83041cab348861e6f4392326/influxdb_client-1.48.0-py3-none-any.whl", hash = "sha256:410db15db761df7ea98adb333c7a03f05bcc2ceef4830cefb7071b888be2b827", size = 746177, upload-time = "2024-11-27T08:26:30.438Z" },
 ]
 
 [[package]]
 name = "paho-mqtt"
 version = "2.1.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/39/15/0a6214e76d4d32e7f663b109cf71fb22561c2be0f701d67f93950cd40542/paho_mqtt-2.1.0.tar.gz", hash = "sha256:12d6e7511d4137555a3f6ea167ae846af2c7357b10bc6fa4f7c3968fc1723834", size = 148848 }
+sdist = { url = "https://files.pythonhosted.org/packages/39/15/0a6214e76d4d32e7f663b109cf71fb22561c2be0f701d67f93950cd40542/paho_mqtt-2.1.0.tar.gz", hash = "sha256:12d6e7511d4137555a3f6ea167ae846af2c7357b10bc6fa4f7c3968fc1723834", size = 148848, upload-time = "2024-04-29T19:52:55.591Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/c4/cb/00451c3cf31790287768bb12c6bec834f5d292eaf3022afc88e14b8afc94/paho_mqtt-2.1.0-py3-none-any.whl", hash = "sha256:6db9ba9b34ed5bc6b6e3812718c7e06e2fd7444540df2455d2c51bd58808feee", size = 67219 },
+    { url = "https://files.pythonhosted.org/packages/c4/cb/00451c3cf31790287768bb12c6bec834f5d292eaf3022afc88e14b8afc94/paho_mqtt-2.1.0-py3-none-any.whl", hash = "sha256:6db9ba9b34ed5bc6b6e3812718c7e06e2fd7444540df2455d2c51bd58808feee", size = 67219, upload-time = "2024-04-29T19:52:48.345Z" },
 ]
 
 [[package]]
@@ -108,18 +108,18 @@ source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "six" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
+    { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
 ]
 
 [[package]]
 name = "python-dotenv"
 version = "1.1.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920 }
+sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 },
+    { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" },
 ]
 
 [[package]]
@@ -129,86 +129,86 @@ source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "typing-extensions" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/ef/63/f776322df4d7b456446eff78c4e64f14c3c26d57d46b4e06c18807d5d99c/reactivex-4.0.4.tar.gz", hash = "sha256:e912e6591022ab9176df8348a653fe8c8fa7a301f26f9931c9d8c78a650e04e8", size = 119177 }
+sdist = { url = "https://files.pythonhosted.org/packages/ef/63/f776322df4d7b456446eff78c4e64f14c3c26d57d46b4e06c18807d5d99c/reactivex-4.0.4.tar.gz", hash = "sha256:e912e6591022ab9176df8348a653fe8c8fa7a301f26f9931c9d8c78a650e04e8", size = 119177, upload-time = "2022-07-16T07:11:53.689Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/69/3f/2ed8c1b8fe3fc2ed816ba40554ef703aad8c51700e2606c139fcf9b7f791/reactivex-4.0.4-py3-none-any.whl", hash = "sha256:0004796c420bd9e68aad8e65627d85a8e13f293de76656165dffbcb3a0e3fb6a", size = 217791 },
+    { url = "https://files.pythonhosted.org/packages/69/3f/2ed8c1b8fe3fc2ed816ba40554ef703aad8c51700e2606c139fcf9b7f791/reactivex-4.0.4-py3-none-any.whl", hash = "sha256:0004796c420bd9e68aad8e65627d85a8e13f293de76656165dffbcb3a0e3fb6a", size = 217791, upload-time = "2022-07-16T07:11:52.061Z" },
 ]
 
 [[package]]
 name = "ruff"
-version = "0.11.6"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d9/11/bcef6784c7e5d200b8a1f5c2ddf53e5da0efec37e6e5a44d163fb97e04ba/ruff-0.11.6.tar.gz", hash = "sha256:bec8bcc3ac228a45ccc811e45f7eb61b950dbf4cf31a67fa89352574b01c7d79", size = 4010053 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/6e/1f/8848b625100ebcc8740c8bac5b5dd8ba97dd4ee210970e98832092c1635b/ruff-0.11.6-py3-none-linux_armv6l.whl", hash = "sha256:d84dcbe74cf9356d1bdb4a78cf74fd47c740bf7bdeb7529068f69b08272239a1", size = 10248105 },
-    { url = "https://files.pythonhosted.org/packages/e0/47/c44036e70c6cc11e6ee24399c2a1e1f1e99be5152bd7dff0190e4b325b76/ruff-0.11.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9bc583628e1096148011a5d51ff3c836f51899e61112e03e5f2b1573a9b726de", size = 11001494 },
-    { url = "https://files.pythonhosted.org/packages/ed/5b/170444061650202d84d316e8f112de02d092bff71fafe060d3542f5bc5df/ruff-0.11.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2959049faeb5ba5e3b378709e9d1bf0cab06528b306b9dd6ebd2a312127964a", size = 10352151 },
-    { url = "https://files.pythonhosted.org/packages/ff/91/f02839fb3787c678e112c8865f2c3e87cfe1744dcc96ff9fc56cfb97dda2/ruff-0.11.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63c5d4e30d9d0de7fedbfb3e9e20d134b73a30c1e74b596f40f0629d5c28a193", size = 10541951 },
-    { url = "https://files.pythonhosted.org/packages/9e/f3/c09933306096ff7a08abede3cc2534d6fcf5529ccd26504c16bf363989b5/ruff-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a4b9a4e1439f7d0a091c6763a100cef8fbdc10d68593df6f3cfa5abdd9246e", size = 10079195 },
-    { url = "https://files.pythonhosted.org/packages/e0/0d/a87f8933fccbc0d8c653cfbf44bedda69c9582ba09210a309c066794e2ee/ruff-0.11.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5edf270223dd622218256569636dc3e708c2cb989242262fe378609eccf1308", size = 11698918 },
-    { url = "https://files.pythonhosted.org/packages/52/7d/8eac0bd083ea8a0b55b7e4628428203441ca68cd55e0b67c135a4bc6e309/ruff-0.11.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f55844e818206a9dd31ff27f91385afb538067e2dc0beb05f82c293ab84f7d55", size = 12319426 },
-    { url = "https://files.pythonhosted.org/packages/c2/dc/d0c17d875662d0c86fadcf4ca014ab2001f867621b793d5d7eef01b9dcce/ruff-0.11.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d8f782286c5ff562e4e00344f954b9320026d8e3fae2ba9e6948443fafd9ffc", size = 11791012 },
-    { url = "https://files.pythonhosted.org/packages/f9/f3/81a1aea17f1065449a72509fc7ccc3659cf93148b136ff2a8291c4bc3ef1/ruff-0.11.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01c63ba219514271cee955cd0adc26a4083df1956d57847978383b0e50ffd7d2", size = 13949947 },
-    { url = "https://files.pythonhosted.org/packages/61/9f/a3e34de425a668284e7024ee6fd41f452f6fa9d817f1f3495b46e5e3a407/ruff-0.11.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15adac20ef2ca296dd3d8e2bedc6202ea6de81c091a74661c3666e5c4c223ff6", size = 11471753 },
-    { url = "https://files.pythonhosted.org/packages/df/c5/4a57a86d12542c0f6e2744f262257b2aa5a3783098ec14e40f3e4b3a354a/ruff-0.11.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4dd6b09e98144ad7aec026f5588e493c65057d1b387dd937d7787baa531d9bc2", size = 10417121 },
-    { url = "https://files.pythonhosted.org/packages/58/3f/a3b4346dff07ef5b862e2ba06d98fcbf71f66f04cf01d375e871382b5e4b/ruff-0.11.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:45b2e1d6c0eed89c248d024ea95074d0e09988d8e7b1dad8d3ab9a67017a5b03", size = 10073829 },
-    { url = "https://files.pythonhosted.org/packages/93/cc/7ed02e0b86a649216b845b3ac66ed55d8aa86f5898c5f1691797f408fcb9/ruff-0.11.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd40de4115b2ec4850302f1a1d8067f42e70b4990b68838ccb9ccd9f110c5e8b", size = 11076108 },
-    { url = "https://files.pythonhosted.org/packages/39/5e/5b09840fef0eff1a6fa1dea6296c07d09c17cb6fb94ed5593aa591b50460/ruff-0.11.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:77cda2dfbac1ab73aef5e514c4cbfc4ec1fbef4b84a44c736cc26f61b3814cd9", size = 11512366 },
-    { url = "https://files.pythonhosted.org/packages/6f/4c/1cd5a84a412d3626335ae69f5f9de2bb554eea0faf46deb1f0cb48534042/ruff-0.11.6-py3-none-win32.whl", hash = "sha256:5151a871554be3036cd6e51d0ec6eef56334d74dfe1702de717a995ee3d5b287", size = 10485900 },
-    { url = "https://files.pythonhosted.org/packages/42/46/8997872bc44d43df986491c18d4418f1caff03bc47b7f381261d62c23442/ruff-0.11.6-py3-none-win_amd64.whl", hash = "sha256:cce85721d09c51f3b782c331b0abd07e9d7d5f775840379c640606d3159cae0e", size = 11558592 },
-    { url = "https://files.pythonhosted.org/packages/d7/6a/65fecd51a9ca19e1477c3879a7fda24f8904174d1275b419422ac00f6eee/ruff-0.11.6-py3-none-win_arm64.whl", hash = "sha256:3567ba0d07fb170b1b48d944715e3294b77f5b7679e8ba258199a250383ccb79", size = 10682766 },
+version = "0.11.10"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" },
+    { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" },
+    { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" },
+    { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" },
+    { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" },
+    { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" },
+    { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" },
+    { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" },
+    { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" },
+    { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" },
+    { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" },
+    { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" },
+    { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" },
+    { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" },
+    { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" },
+    { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" },
+    { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" },
 ]
 
 [[package]]
 name = "setuptools"
-version = "79.0.0"
+version = "80.7.1"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/7d/19/fecb7e2825616270f34512b3394cdcf6f45a79b5b6d94fdbd86a509e67b5/setuptools-79.0.0.tar.gz", hash = "sha256:9828422e7541213b0aacb6e10bbf9dd8febeaa45a48570e09b6d100e063fc9f9", size = 1367685 }
+sdist = { url = "https://files.pythonhosted.org/packages/9e/8b/dc1773e8e5d07fd27c1632c45c1de856ac3dbf09c0147f782ca6d990cf15/setuptools-80.7.1.tar.gz", hash = "sha256:f6ffc5f0142b1bd8d0ca94ee91b30c0ca862ffd50826da1ea85258a06fd94552", size = 1319188, upload-time = "2025-05-15T02:41:00.955Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/cc/ea/d53f2f8897c46a36df085964d07761ea4c2d1f2cf92019693b6742b7aabb/setuptools-79.0.0-py3-none-any.whl", hash = "sha256:b9ab3a104bedb292323f53797b00864e10e434a3ab3906813a7169e4745b912a", size = 1256065 },
+    { url = "https://files.pythonhosted.org/packages/a1/18/0e835c3a557dc5faffc8f91092f62fc337c1dab1066715842e7a4b318ec4/setuptools-80.7.1-py3-none-any.whl", hash = "sha256:ca5cc1069b85dc23070a6628e6bcecb3292acac802399c7f8edc0100619f9009", size = 1200776, upload-time = "2025-05-15T02:40:58.887Z" },
 ]
 
 [[package]]
 name = "six"
 version = "1.17.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
+    { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
 ]
 
 [[package]]
 name = "sqlparse"
 version = "0.5.3"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999 }
+sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999, upload-time = "2024-12-10T12:05:30.728Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415 },
+    { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" },
 ]
 
 [[package]]
 name = "typing-extensions"
 version = "4.13.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967 }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806 },
+    { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
 ]
 
 [[package]]
 name = "tzdata"
 version = "2025.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 }
+sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 },
+    { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
 ]
 
 [[package]]
 name = "urllib3"
 version = "2.4.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 }
+sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
+    { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" },
 ]
diff --git a/docker-compose.yaml b/docker-compose.yaml
index eac4c3cea511ca96ffb7848c70aac1c18b86285e..a31683dab409468578760ebf0fa5a7ac496e05cf 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,14 +1,14 @@
 
-services:
+services: 
 
   stream-processing:
     build:
-      context: ./backend
-      dockerfile: stream_processing/Dockerfile
+      context: ./stream_processing
+      dockerfile: Dockerfile
     image: stream-processing
     container_name: stream-processing
     volumes:
-      - ./backend/stream_processing:/app/backend/stream_processing
+      - ./stream_processing/mac_to_room.json:/app/mac_to_room.json
     env_file:
       - ./backend/.env.docker
     restart: unless-stopped
@@ -30,7 +30,9 @@ services:
       - ./backend:/app
 
   frontend:
-    build: ./frontend
+    build:
+      context: ./frontend
+      dockerfile: Dockerfile
     ports:
       - "5173:5173"
     volumes:
@@ -60,7 +62,7 @@ services:
     ports:
       - "8081:80"  # Port 80 im Container auf 8081 lokal mappen
     restart: unless-stopped
-  
+
   influxdb2:
     image: influxdb:2
     ports:
diff --git a/ordnerstruktur.txt b/ordnerstruktur.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5f44b9a64699799e9779974f474081db9c072d6b
Binary files /dev/null and b/ordnerstruktur.txt differ
diff --git a/services/influxdb/influxdb2-admin-password b/services/influxdb/influxdb2-admin-password
index f3097ab13082b70f67202aab7dd9d1b35b7ceac2..7aa311adf93ff404972ea5e75ff97253cd32ecbd 100644
--- a/services/influxdb/influxdb2-admin-password
+++ b/services/influxdb/influxdb2-admin-password
@@ -1 +1 @@
-password
+password
\ No newline at end of file
diff --git a/services/influxdb/influxdb2-admin-token b/services/influxdb/influxdb2-admin-token
index 6f3eee4c3f44dab3c69b3a9d3107e8e53fe6d4d0..e14dde2927d98444a7eb5cc3751fe5004734f826 100644
--- a/services/influxdb/influxdb2-admin-token
+++ b/services/influxdb/influxdb2-admin-token
@@ -1 +1 @@
-w-Isk1D35T90Srj_auFTxsbksn1zRB5MiNZf6h6RuNdb9-2s9ie5c1488JqoYILKrceVm0LaE5KCN2dXdDM-jA==
\ No newline at end of file
+1xa5lLACRZDYsvinhABndZ8GGzBY7-gTQsAf309c0aTnPPtBxixPEEOPuXLmkTxUKy8golKae6fsrh1wD4SL0A==
\ No newline at end of file
diff --git a/services/influxdb/influxdb2-admin-username b/services/influxdb/influxdb2-admin-username
index 7fbe952b76a23b08b5c0de1a519d416ada70765c..f77b00407e0f55d50bdd6fe337469924f2b9d705 100644
--- a/services/influxdb/influxdb2-admin-username
+++ b/services/influxdb/influxdb2-admin-username
@@ -1 +1 @@
-admin
+admin
\ No newline at end of file
diff --git a/backend/stream_processing/Dockerfile b/stream_processing/Dockerfile
similarity index 79%
rename from backend/stream_processing/Dockerfile
rename to stream_processing/Dockerfile
index 9849897e0380cea497e90741520638df106bc3c4..92ee13778cd0d11294f839a46803a3ccd11f41e3 100644
--- a/backend/stream_processing/Dockerfile
+++ b/stream_processing/Dockerfile
@@ -1,11 +1,10 @@
-# Verwende das neueste Python-Image
 FROM python:latest
 
 # Setze das Arbeitsverzeichnis im Container
 WORKDIR /app
 
 # Kopiere die pyproject.toml und uv.lock aus dem Backend-Hauptverzeichnis
-COPY ../pyproject.toml ../uv.lock ./
+COPY . .
 
 # Installiere pip und uv
 RUN pip install --upgrade pip && \
@@ -19,13 +18,14 @@ RUN uv venv .venv && \
 RUN uv sync
 
 # Kopiere NUR den Stream-Processing-Code
-COPY . .
+#COPY . .
 
 # Optional: Kopiere ggf. auch andere Module aus dem Backend, falls du darauf zugreifen willst
-COPY ../utils ../utils
+#COPY utils utils
 
 # Setze Umgebungsvariablen
 ENV PYTHONUNBUFFERED=1
 
 # Startbefehl für das Stream-Processing
-CMD ["uv", "run", "python", "-m", "backend.stream_processing.main"]
+CMD ["uv", "run", "python", "-m", "main"]
+
diff --git a/backend/stream_processing/__init__.py b/stream_processing/__init__.py
similarity index 100%
rename from backend/stream_processing/__init__.py
rename to stream_processing/__init__.py
diff --git a/stream_processing/jsonhandler.py b/stream_processing/jsonhandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6d11267b87ccdce1e2f172c8fe249154b29f5f7
--- /dev/null
+++ b/stream_processing/jsonhandler.py
@@ -0,0 +1,27 @@
+import json
+import os
+
+def load_json(file_name: str) -> dict:
+    """
+    ladet eine JSON Datei, wenn diese existiert,
+    und gibt diese als dictionary zurück
+    key : value
+    """
+    print("JSONHANDLER")
+    if not os.path.exists(file_name):
+        print("FILE IST OFFEN")
+        return {}
+    with open(file_name) as f:
+        mac_room_mapping = json.load(f)
+    return mac_room_mapping
+
+def write_json(mac_room_mapping: dict, file_name: str):
+    print("ES SCHREIBT IN JASON")
+    try:
+        print(f"→ Schreibe Datei: {file_name}")
+        with open(file_name, "w") as f:
+            print("FILE IST OPEN")
+            json.dump(mac_room_mapping, f, indent=4)
+        print("✅ Datei erfolgreich geschrieben")
+    except Exception as e:
+        print("❌ Fehler beim Schreiben:", e)
diff --git a/backend/stream_processing/mQTTClientHandler.py b/stream_processing/mQTTClientHandler.py
similarity index 93%
rename from backend/stream_processing/mQTTClientHandler.py
rename to stream_processing/mQTTClientHandler.py
index 5d2d022ac3277c1ae86b81406b9cd660b9227d89..0ed9e77d29f27ed48f3eb784f80ff59736bf1233 100644
--- a/backend/stream_processing/mQTTClientHandler.py
+++ b/stream_processing/mQTTClientHandler.py
@@ -3,7 +3,7 @@ import json
 from utils.loggingFactory import LoggerFactory
 from datetime import datetime
 import paho.mqtt.client as mqtt
-from stream_processing import jsonhandler
+import jsonhandler
 from utils.influx import InfluxDBHelper
 import os
 
@@ -24,7 +24,9 @@ class MQTTClientHandler:
     # Konstruktor
     def __init__(
         self, broker_url: str, topic: str, influx_writer: InfluxDBHelper
+        
     ):
+        print("DAS IST EIN TEST")
         self.logger = LoggerFactory.get_logger(__name__)
         # key: mac : value : room
         self.mac_to_room = jsonhandler.load_json(self.MAPPING_FILE_NAME)
@@ -38,6 +40,7 @@ class MQTTClientHandler:
 
     def on_connect(self, client, userdata, flags, rc):
         self.logger.info("Connected with result code " + str(rc))
+        print("Connected")
         client.subscribe(self.topic)
         self.logger.info("Subscribed to " + self.topic)
 
@@ -48,6 +51,9 @@ class MQTTClientHandler:
         self: ist die MQTTClientHandler instanz, die wird gebraucht um die Einträge in
         die InfluxDB zu schreiben
         """
+
+        print("Message")
+        
         msg = json.loads(msg.payload)
         metadate = msg["metadata"]
 
@@ -60,15 +66,18 @@ class MQTTClientHandler:
             self.logger.warning(
                 f"Neue MAC-Adresse gefunden: {mac}. Mapping wird ergänzt."
             )
+            print("MAC war nicht in File")
             self.mac_to_room[mac] = ""  # leerer Platzhalter
             jsonhandler.write_json(self.mac_to_room, self.MAPPING_FILE_NAME)
             self.mac_to_room = jsonhandler.load_json(self.MAPPING_FILE_NAME)
+            print("keine Ahnung")
             return
 
         self.write_to_influxDB(msg, metadate)
 
     def write_to_influxDB(self, msg: dict, metadate: dict):
         try:
+            print(msg)
             self.influx_writer.write_point(
                 measurement=self.MEASUREMENT_NAME,
                 tags={
diff --git a/backend/stream_processing/mac_to_room.json b/stream_processing/mac_to_room.json
similarity index 91%
rename from backend/stream_processing/mac_to_room.json
rename to stream_processing/mac_to_room.json
index c1859795fd05782fd926b4f99a1234d3dac1c260..426b33c7b1b7c68af29847a47bf7aba221efbe94 100644
--- a/backend/stream_processing/mac_to_room.json
+++ b/stream_processing/mac_to_room.json
@@ -17,5 +17,7 @@
     "a1:b2:c3:d4:e5:f6": "",
     "77:88:99:aa:bb:cc": "",
     "test": "",
-    "aaron": ""
+    "aaron": "",
+    "AAFF": "",
+    "AAFFEE": ""
 }
\ No newline at end of file
diff --git a/backend/stream_processing/main.py b/stream_processing/main.py
similarity index 62%
rename from backend/stream_processing/main.py
rename to stream_processing/main.py
index 4679c3afb2670c97bc5953b2ccd97a51b43f2686..eefb9124f9300f910be1d0c96acc6544a6b6e248 100644
--- a/backend/stream_processing/main.py
+++ b/stream_processing/main.py
@@ -1,19 +1,28 @@
 from dotenv import load_dotenv
 import os
-from stream_processing.mQTTClientHandler import MQTTClientHandler
+from mQTTClientHandler import MQTTClientHandler
 from utils.influx import InfluxDBHelper
 
 load_dotenv()
 
 
 def main():
+    print("🟢 Stream-Processing gestartet", flush=True)
     influx_writer = InfluxDBHelper(
         url=os.getenv("INFLUXDB_URL"),
         token=os.getenv("INFLUXDB_TOKEN"),
         org=os.getenv("INFLUXDB_ORG"),
         bucket=os.getenv("INFLUXDB_BUCKET"),
+
+        
     )
 
+    print("== ENV =="),
+    print("TOKEN:", os.getenv("INFLUXDB_TOKEN")),
+    print("URL:", os.getenv("INFLUXDB_URL")),
+    print("ORG:", os.getenv("INFLUXDB_ORG")),
+    print("BUCKET:", os.getenv("INFLUXDB_BUCKET")),
+
     mqtt_handler = MQTTClientHandler(
         broker_url=os.getenv("MQTT_BROKER_URL"),
         topic=os.getenv("MQTT_TOPIC"),
diff --git a/stream_processing/pyproject.toml b/stream_processing/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..6efd3146e628d69c6e93210f064597ca6a2ed2e0
--- /dev/null
+++ b/stream_processing/pyproject.toml
@@ -0,0 +1,46 @@
+[project]
+name = "backend"
+version = "0.1.0"
+description = "backend of co2 web service"
+authors = [
+  {name = "Patrick Ade",    email = "21adpa1bif@hft-stuttgart.de"},
+  {name = "Morten Stetter", email = "22stmo1bif@hft-stuttgart.de"},
+  {name = "Aaron Mele",     email = "21meaa1bif@hft-stuttgart.de"},
+  {name = "Emre Gezer",     email = "21geem1bif@hft-stuttgart.de"},
+]
+maintainers = [
+  {name = "Max Mustermann", email = "mustermann@example.com"}
+]
+readme = "README.md"
+keywords = ["co2", "sensor", "temperature", "humidity", "monitor", "monitoring", "air quality"]
+
+requires-python = ">=3.12"
+dependencies = [
+    "influxdb-client>=1.40",
+    "python-dotenv>=1.1",
+    "paho-mqtt>=2.1",
+]
+
+[dependency-groups]
+dev = [
+    "ruff>=0.11.5"
+]
+
+[tool.ruff]
+# Set the maximum line length to 80.
+line-length = 80
+
+[tool.ruff.lint]
+# Add the `line-too-long` rule to the enforced rule set.
+extend-select = ["E501"]
+
+
+#[build-system]
+#requires = ["setuptools" ] #"wheel"
+#build-backend = "setuptools.build_meta"
+
+#[tool.setuptools]
+#package-dir = {"" = "."}
+
+#[tool.setuptools.packages.find]
+#where = ["backend"]
diff --git a/stream_processing/utils/__init__.py b/stream_processing/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/stream_processing/utils/fluxQueryBuilder.py b/stream_processing/utils/fluxQueryBuilder.py
new file mode 100644
index 0000000000000000000000000000000000000000..16eb1cca317bdbc2583f340a313ff40d20f49fa0
--- /dev/null
+++ b/stream_processing/utils/fluxQueryBuilder.py
@@ -0,0 +1,103 @@
+from typing import List, Optional
+
+
+class FluxQueryBuilder:
+    """
+    A builder class for constructing Flux queries (InfluxDB 2.x).
+    Supports fluent method chaining for readable query construction.
+
+    Example:
+        query = (
+            FluxQueryBuilder()
+            .bucket("sensor_data")
+            .time_range("-1h", "now()")
+            .filter_measurement("sensor_data")
+            .filter_fields("co2", "temperature", "humidity")
+            .filter_field("room", "1/210")
+            .pivot()
+            .mean()
+            .build()
+        )
+    """
+
+    def __init__(self) -> None:
+        self._bucket: Optional[str] = None
+        self._start: Optional[str] = None
+        self._stop: Optional[str] = None
+        self._measurement: Optional[str] = None
+        self._fields: List[str] = []
+        self._field_filters: dict = {}  # e.g. {"room": "1/210"}
+        self._use_mean: bool = False
+        self._use_pivot: bool = False
+
+    def bucket(self, name: str) -> "FluxQueryBuilder":
+        """Set the InfluxDB bucket name."""
+        self._bucket = name
+        return self
+
+    def time_range(self, start: str, stop: str) -> "FluxQueryBuilder":
+        """Set time range for the query."""
+        self._start = start
+        self._stop = stop
+        return self
+
+    def filter_measurement(self, measurement: str) -> "FluxQueryBuilder":
+        """Filter for a specific _measurement value."""
+        self._measurement = measurement
+        return self
+
+    def filter_field(self, field: str, value: str) -> "FluxQueryBuilder":
+        """Add a tag filter like r["room"] == "1/210"."""
+        self._field_filters[field] = value
+        return self
+
+    def filter_fields(self, *fields: str) -> "FluxQueryBuilder":
+        """Filter for multiple _field values using OR."""
+        self._fields.extend(fields)
+        return self
+
+    def mean(self) -> "FluxQueryBuilder":
+        """Apply mean() aggregation."""
+        self._use_mean = True
+        return self
+
+    def pivot(self) -> "FluxQueryBuilder":
+        """Apply pivot() to restructure results with multiple fields per timestamp."""
+        self._use_pivot = True
+        return self
+
+    def build(self) -> str:
+        """Construct and return the final Flux query string."""
+        if not self._bucket:
+            raise ValueError("Bucket name is required.")
+        if not (self._start and self._stop):
+            raise ValueError("Start and stop times are required.")
+        if not self._measurement:
+            raise ValueError("Measurement is required.")
+
+        lines: List[str] = []
+        lines.append(f'from(bucket: "{self._bucket}")')
+        lines.append(f'  |> range(start: {self._start}, stop: {self._stop})')
+        lines.append(f'  |> filter(fn: (r) => r["_measurement"] == "{self._measurement}")')
+
+        # Optional tag filters (e.g., room or mac)
+        for key, value in self._field_filters.items():
+            lines.append(f'  |> filter(fn: (r) => r["{key}"] == "{value}")')
+
+        # Optional field filters (_field == ...)
+        if self._fields:
+            or_expr = " or ".join(f'r["_field"] == "{f}"' for f in self._fields)
+            lines.append(f'  |> filter(fn: (r) => {or_expr})')
+
+        if self._use_mean:
+            lines.append('  |> mean()')
+
+        if self._use_pivot:
+            lines.append('  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")')
+
+        return "\n".join(lines)
+
+    def reset(self) -> "FluxQueryBuilder":
+        """Reset the builder so a new query can be built from scratch."""
+        self.__init__()
+        return self
diff --git a/stream_processing/utils/influx.py b/stream_processing/utils/influx.py
new file mode 100644
index 0000000000000000000000000000000000000000..44fa5c39fac94911d50dd5db03a5e34af74dbb43
--- /dev/null
+++ b/stream_processing/utils/influx.py
@@ -0,0 +1,52 @@
+import os
+from influxdb_client import InfluxDBClient, Point, WritePrecision
+from influxdb_client.client.write_api import WriteOptions
+
+
+class InfluxDBHelper:
+    def __init__(self, url: str, token: str, org: str, bucket: str):
+        self.client = InfluxDBClient(url=url, token=token, org=org)
+        self.bucket = bucket
+        self.org = org
+        self.query_api = self.client.query_api()
+        # self.write_api = self.client.write_api(write_options=SYNCHRONOUS) good for debug
+        self.write_api = self.client.write_api(
+            write_options=WriteOptions(batch_size=1000, flush_interval=10000)
+        )
+
+    def write_point(
+        self, measurement: str, tags: dict, fields: dict, timestamp=None
+    ):
+        """ """
+        point = Point(measurement)
+        for k, v in tags.items():
+            point.tag(k, v)
+        for k, v in fields.items():
+            point.field(k, v)
+        if timestamp:
+            point.time(timestamp, WritePrecision.NS)
+        self.write_api.write(bucket=self.bucket, org=self.org, record=point)
+            
+    def ping(self) -> bool:
+        return self.client.ping()
+
+    def get_all_data(self):
+        """ """
+        query = f'''
+            from(bucket: "{self.bucket}")
+                |> range(start: -20d)
+                |> filter(fn: (r) => r["_measurement"] == "sensor_data")
+        '''
+        return self.query_api.query(org=self.org, query=query)
+
+    def get_latest_room_data(self, room_id: str):
+        """ """
+        query = f'''
+            from(bucket: "{self.bucket}")
+                |> range(start: -5m)
+                |> filter(fn: (r) => r["_measurement"] == "co2")
+                |> filter(fn: (r) => r["room"] == "{room_id}")
+                |> last()
+        '''
+        return self.query_api.query(org=self.org, query=query)
+
diff --git a/stream_processing/utils/init.py b/stream_processing/utils/init.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/stream_processing/utils/loggingFactory.py b/stream_processing/utils/loggingFactory.py
new file mode 100644
index 0000000000000000000000000000000000000000..2cc12bf6f4162805eec6c80ce2edfd83ff1d1c8f
--- /dev/null
+++ b/stream_processing/utils/loggingFactory.py
@@ -0,0 +1,37 @@
+import logging
+import os
+from logging.handlers import RotatingFileHandler
+
+LOG_DIR = "logs"
+LOG_FILE = "app.log"
+LOG_PATH = os.path.join(LOG_DIR, LOG_FILE)
+
+
+class LoggerFactory:
+    # logger.info("Connected with result code %s", str(rc))
+    # logger.warning("Neue MAC-Adresse gefunden: %s", mac)
+    # logger.error("Failed writing to InfluxDb: %s", e)
+
+    @staticmethod
+    def get_logger(name: str, level=logging.DEBUG) -> logging.Logger:
+        if not os.path.exists(LOG_DIR):
+            os.makedirs(LOG_DIR)
+
+        logger = logging.getLogger(name)
+        if logger.hasHandlers():
+            return logger  # vermeidet doppelte Handler
+
+        logger.setLevel(level)
+
+        formatter = logging.Formatter(
+            "[%(asctime)s] %(levelname)s in %(name)s: %(message)s",
+            datefmt="%Y-%m-%d %H:%M:%S",
+        )
+
+        file_handler = RotatingFileHandler(
+            LOG_PATH, maxBytes=5_000_000, backupCount=5
+        )
+        file_handler.setFormatter(formatter)
+        logger.addHandler(file_handler)
+
+        return logger