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