diff --git a/.gitignore b/.gitignore index 103d74d1b3cdc94a7c42ee74b6bcaa1718dcc7ab..c7da6fadcb50305aa861c80596acca32c1d3cb0d 100644 --- a/.gitignore +++ b/.gitignore @@ -203,3 +203,28 @@ pnpm-debug.log* *.njsproj *.sln *.sw? +################################# +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d6c5504af16c9b058eb099859d9b678c2589c908 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,5 @@ +## ToDo +Docker compose in Services/Influxdb und Services/mqtt zu einem dockerfile machen und das über die große docker compose im "Web" ordner starten +Streamprocessing die Dockerfile auf uv umstellen und .requirements in .toml file reinmachen (dafür auch entsprechend entfernen) + +Recherche ob in yaml files auch dependencies rein können - wenn ja können wir ein einziges Dockerfile machen. !!! Wichtig!!! \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index 100e143c2cc7452546b11468d95c5f4084afd7f1..d59a7855c96b5e7fbcfe32f43c9bb8d1d99249a7 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -4,26 +4,28 @@ FROM python:latest # Setze das Arbeitsverzeichnis im Container WORKDIR /app -# Kopiere die pyproject.toml und uv.lock-Dateien -COPY pyproject.toml . -COPY uv.lock . - -# Kopiere auch requirements.txt, falls vorhanden -COPY requirements.txt . -# Nutze uv -# Installiere uv und die Abhängigkeiten +# Kopiere Projektdateien für Abhängigkeitsmanagement +COPY pyproject.toml uv.lock ./ + +# Installiere pip und uv RUN pip install --upgrade pip && \ - pip install uv && \ - pip install --no-cache-dir -r requirements.txt + pip install uv + +# Erstelle und aktiviere ein virtuelles Environment +RUN uv venv .venv && \ + . .venv/bin/activate + +# Installiere die Abhängigkeiten aus pyproject.toml +RUN uv sync # Kopiere den Rest des Projekts in den Container COPY . . # Setze Umgebungsvariablen, falls nötig -ENV PYTHONUNBUFFERED 1 +ENV PYTHONUNBUFFERED=1 -# Exponiere den Port 8000 für den Server +# Exponiere Port 8000 (für Django) EXPOSE 8000 -# Der Startbefehl: Starte den Server mit uv +# Startbefehl (z. B. für Django-Projekt) CMD ["uv", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"] diff --git a/backend/stream_processing/Dockerfile b/backend/stream_processing/Dockerfile index 100e143c2cc7452546b11468d95c5f4084afd7f1..9849897e0380cea497e90741520638df106bc3c4 100644 --- a/backend/stream_processing/Dockerfile +++ b/backend/stream_processing/Dockerfile @@ -4,26 +4,28 @@ FROM python:latest # Setze das Arbeitsverzeichnis im Container WORKDIR /app -# Kopiere die pyproject.toml und uv.lock-Dateien -COPY pyproject.toml . -COPY uv.lock . - -# Kopiere auch requirements.txt, falls vorhanden -COPY requirements.txt . -# Nutze uv -# Installiere uv und die Abhängigkeiten +# Kopiere die pyproject.toml und uv.lock aus dem Backend-Hauptverzeichnis +COPY ../pyproject.toml ../uv.lock ./ + +# Installiere pip und uv RUN pip install --upgrade pip && \ - pip install uv && \ - pip install --no-cache-dir -r requirements.txt + pip install uv + +# Erstelle und aktiviere ein virtuelles Environment +RUN uv venv .venv && \ + . .venv/bin/activate + +# Installiere die Abhängigkeiten aus pyproject.toml +RUN uv sync -# Kopiere den Rest des Projekts in den Container +# Kopiere NUR den Stream-Processing-Code COPY . . -# Setze Umgebungsvariablen, falls nötig -ENV PYTHONUNBUFFERED 1 +# Optional: Kopiere ggf. auch andere Module aus dem Backend, falls du darauf zugreifen willst +COPY ../utils ../utils -# Exponiere den Port 8000 für den Server -EXPOSE 8000 +# Setze Umgebungsvariablen +ENV PYTHONUNBUFFERED=1 -# Der Startbefehl: Starte den Server mit uv -CMD ["uv", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"] +# Startbefehl für das Stream-Processing +CMD ["uv", "run", "python", "-m", "backend.stream_processing.main"] diff --git a/docker-compose.yaml b/docker-compose.yaml index 1294bb0961adbe9ad94f7f3fb1a664d9acbf38dc..024b1257e2e92cdda70912105363127932824b8c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,24 +2,29 @@ services: stream-processing: + build: + context: ./backend + dockerfile: stream_processing/Dockerfile image: stream-processing container_name: stream-processing - build: ./backend/stream_processing - command: uv run -m backend.stream_processing.main env_file: - - ../backend/.env + - ./backend/.env restart: unless-stopped - #depends_on: - # - influxdb - # - mosquitto + depends_on: + - influxdb2 + - mosquitto - backend: + backend-django: + build: + context: ./backend + dockerfile: Dockerfile image: django-backend container_name: django-backend - build: ./backend + env_file: + - ./backend/.env ports: - "8000:8000" - volumes: # was ist volumes + volumes: - ./backend:/app frontend: @@ -31,3 +36,54 @@ services: - /app/node_modules stdin_open: true tty: true + + mosquitto: + image: eclipse-mosquitto:latest + container_name: mosquitto-broker + volumes: + - ./services/mqtt/config:/mosquitto/config + - ./services/mqtt/data:/mosquitto/data + - ./services/mqtt/log:/mosquitto/log + - ./services/mqtt/mosquitto:/mosquitto + ports: + - "1883:1883" + - "8883:8883" + - "9001:9001" + stdin_open: true + tty: true + + influxdb2: + image: influxdb:2 + ports: + - 8086:8086 + environment: + DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_USERNAME_FILE: /run/secrets/influxdb2-admin-username + DOCKER_INFLUXDB_INIT_PASSWORD_FILE: /run/secrets/influxdb2-admin-password + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN_FILE: /run/secrets/influxdb2-admin-token + DOCKER_INFLUXDB_INIT_ORG: docs + DOCKER_INFLUXDB_INIT_BUCKET: home + secrets: + - influxdb2-admin-username + - influxdb2-admin-password + - influxdb2-admin-token + volumes: + - type: volume + source: influxdb2-data + target: /var/lib/influxdb2 + - type: volume + source: influxdb2-config + target: /etc/influxdb2 + +secrets: + influxdb2-admin-username: + file: ./services/influxdb/influxdb2-admin-username + influxdb2-admin-password: + file: ./services/influxdb/influxdb2-admin-password + influxdb2-admin-token: + file: ./services/influxdb/influxdb2-admin-token + +volumes: + influxdb2-data: + influxdb2-config: + diff --git a/frontend/.gitignore b/frontend/.gitignore deleted file mode 100644 index a547bf36d8d11a4f89c59c144f24795749086dd1..0000000000000000000000000000000000000000 --- a/frontend/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b956a2d3c72f5e4e0f5e405ecab5cf99218f1fc7..8558402d9ab4ae5a463aa49b214db25e905786f8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,9 @@ "name": "frontend", "version": "0.0.0", "dependencies": { - "vue": "^3.5.13" + "chart.js": "^4.4.0", + "vue": "^3.5.13", + "vue-chartjs": "^5.3.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", @@ -492,6 +494,11 @@ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "license": "MIT" }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.40.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz", @@ -893,6 +900,17 @@ "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", "license": "MIT" }, + "node_modules/chart.js": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.9.tgz", + "integrity": "sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -1129,18 +1147,17 @@ } }, "node_modules/vite": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.2.tgz", - "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==", + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", - "tinyglobby": "^0.2.12" + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -1223,6 +1240,15 @@ "optional": true } } + }, + "node_modules/vue-chartjs": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.2.tgz", + "integrity": "sha512-NrkbRRoYshbXbWqJkTN6InoDVwVb90C0R7eAVgMWcB9dPikbruaOoTFjFYHE/+tNPdIe6qdLCDjfjPHQ0fw4jw==", + "peerDependencies": { + "chart.js": "^4.1.1", + "vue": "^3.0.0-0 || ^2.7.0" + } } } } diff --git a/frontend/package.json b/frontend/package.json index 24a5e39e5550d96b6924a8173ff214b50fe5ffb9..b46f38cd01dae7c0227112c5b431812c92a176f5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,10 +9,12 @@ "preview": "vite preview" }, "dependencies": { - "vue": "^3.5.13" + "vue": "^3.5.13", + "chart.js": "^4.4.0", + "vue-chartjs": "^5.3.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "vite": "^6.3.2" } -} +} \ No newline at end of file diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 81c28ec8cdf4a4b8f280e82aff7af8f722eefd21..13fbeb02c8e8fc5006a0ca31bba0a244eb235153 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,5 +1,6 @@ <script setup> import HelloWorld from './components/HelloWorld.vue' +import Chart from './components/LiveChart.vue' </script> <template> @@ -11,6 +12,7 @@ import HelloWorld from './components/HelloWorld.vue' <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> </a> </div> + <Chart></Chart> <HelloWorld msg="Vite + Vue" /> </template> diff --git a/frontend/src/components/LiveChart.vue b/frontend/src/components/LiveChart.vue index 91f2fba3e70588a399bd8663c576f2d7b0281244..fea96e51833573d980ea0a6f73c7a31f24245e72 100644 --- a/frontend/src/components/LiveChart.vue +++ b/frontend/src/components/LiveChart.vue @@ -1,12 +1,10 @@ - <template> - <Line :date="charData" :options="chartOptions"/> -</template> + <Line :data="chartData" :options="chartOptions" ref="chartRef" /> + </template> - -<script setup> -import { Line } from 'vue-chartjs' -import { + <script setup> + import { Line } from 'vue-chartjs' + import { Chart as ChartJS, Title, Tooltip, @@ -15,58 +13,64 @@ import { PointElement, LinearScale, CategoryScale -} from 'chart.js' -import { ref, reactive } from 'vue' - -const chartRef = ref() - -ChartJS.register(Title,Tooltip,Legend,LineElement,PointElement,LinearScale,CategoryScale) - -const MAX_POINTS = 100 - -const charData = reactive({ + } from 'chart.js' + import { ref, reactive } from 'vue' + + // Chart.js Module registrieren + ChartJS.register(Title, Tooltip, Legend, LineElement, PointElement, LinearScale, CategoryScale) + + // Refs und Props + const chartRef = ref() + const props = defineProps({ + msg: String, + }) + + // Chart-Daten + const chartData = reactive({ labels: [], - datasets:[ - { - label: 'co2', - data: [], - borderColor: 'rgb(255,99,132)', - tension: 0.1 - }, - { - label: 'humidity', - data: [], - borderColor: 'rgb(255,99,132)', - tension: 0.1 - }, - { - label: 'temperature', - data: [], - borderColor: 'rgb(255,99,132)', - tension: 0.1 - } + datasets: [ + { + label: 'co2', + data: [], + borderColor: 'rgb(255, 99, 132)', + tension: 0.1 + }, + { + label: 'humidity', + data: [], + borderColor: 'rgb(54, 162, 235)', + tension: 0.1 + }, + { + label: 'temperature', + data: [], + borderColor: 'rgb(255, 206, 86)', + tension: 0.1 + } ] -}) - -const chartOptions = { + }) + + // Chart-Optionen + const chartOptions = { responsive: true, animation: false, - scales:{ - y:{ - beginAtZero: true - } + scales: { + y: { + beginAtZero: true + } } -} - -defineExpose({ chartData, + } + + // Methoden nach außen freigeben + defineExpose({ + chartData, updateChart: () => chartRef.value?.chart?.update() -})defineProps({ - msg: String, -}) - -const count = ref(0) - -</script> - -<style scoped> -</style> + }) + + // Beispielzustand + const count = ref(0) + </script> + + <style scoped> + </style> + \ No newline at end of file diff --git a/services/mqtt/compose.yaml b/services/mqtt/compose.yaml index 421cc24dd94388685996ca7a1d85e26a092536a0..3b7d4a838dee3f24666c7be411b0bfbc80dddbec 100644 --- a/services/mqtt/compose.yaml +++ b/services/mqtt/compose.yaml @@ -14,12 +14,3 @@ services: - 9001:9001 # optional für Websockets stdin_open: true tty: true - - # backend: - # build: ./backend - # container_name: backend-app - # ports: - # - "3000:3000" - # depends_on: - # - mosquitto - # restart: unless-stopped diff --git a/services/mqtt/config/mosquitto.conf b/services/mqtt/config/mosquitto.conf old mode 100644 new mode 100755 diff --git a/services/mqtt/data/mosquitto.db b/services/mqtt/data/mosquitto.db index 41467253721ad106db189693a6f4d2a96e3c238d..762cc36a198e6e81bcc6265eb6cb1e53577a0122 100644 Binary files a/services/mqtt/data/mosquitto.db and b/services/mqtt/data/mosquitto.db differ