diff --git a/README.md b/README.md index a4576e5..49da370 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,177 @@ -Gerne, hier ist eine README-Datei für Ihr Angular-Projekt, die die Apache- und Proxy-Server-Komponenten explizit auslässt und sich auf die Angular-Anwendung und ihre Tasmota-Steuerungsfunktionalität konzentriert. +# Homenas Landing Page + +Angular-basierte Homelab-Startseite für das lokale Netzwerk (`neugasse.lan`). +Zeigt Self-Hosted-Services aus Directus als Link-Karten an und ermöglicht die Steuerung von Tasmota-Steckdosen direkt aus dem Browser. --- -# ang-university-httpclient +## Features -Dies ist eine Angular-Anwendung, die als "Homenas Landing Page" dient und speziell für die Steuerung von Tasmota-Smart-Plugs entwickelt wurde. Die Anwendung verwendet `HttpClient` für die Kommunikation mit den Tasmota-Geräten und ist für eine einfache Skalierbarkeit konzipiert, um mehrere Steckdosen zu verwalten. - -## Inhaltsverzeichnis - -- [ang-university-httpclient](#ang-university-httpclient) - - [Inhaltsverzeichnis](#inhaltsverzeichnis) - - [1. Projektbeschreibung](#1-projektbeschreibung) - - [2. Funktionen](#2-funktionen) - - [3. Verwendete Technologien](#3-verwendete-technologien) - - [4. Voraussetzungen](#4-voraussetzungen) - - [5. Installation](#5-installation) - - [6. Entwicklungsserver](#6-entwicklungsserver) - - [7. Code-Struktur (Tasmota-Komponente)](#7-code-struktur-tasmota-komponente) - - [8. Build](#8-build) - - [9. Tests](#9-tests) - - [10. Konfiguration](#10-konfiguration) - - [11. Hinweise zur Tasmota-Optimierung](#11-hinweise-zur-tasmota-optimierung) +- **Service-Übersicht** — Links zu allen Self-Hosted-Diensten, Bilder und Beschreibungen werden dynamisch aus Directus geladen +- **Tasmota-Steuerung** — Ein/Aus-Toggle für Tasmota-Steckdosen direkt über die Web-UI +- **Nginx-Container** — Auslieferung des Angular-Builds über `nginx:stable-alpine` via Docker Compose --- -## 1. Projektbeschreibung +## Stack -`ang-university-httpclient` ist eine Angular-Anwendung, deren Hauptzweck die Steuerung von Tasmota-fähigen Steckdosen ist. Sie bietet eine Benutzeroberfläche zum Abrufen des Status und zum Schalten von Geräten. Das Projekt wurde so refaktorisiert, dass es mehrere Tasmota-Steckdosen über ein Array verwaltet, was die Wartbarkeit und Skalierbarkeit verbessert. +| Komponente | Technologie | +|---|---| +| Frontend | Angular 17.1, Bootstrap 5 | +| CMS / API | Directus | +| Steckdosen | Tasmota (HTTP-API) | +| Webserver | nginx:stable-alpine (Docker) | +| Reverse Proxy | Nginx Proxy Manager | -## 2. Funktionen +--- -* **Tasmota-Steuerung:** Schaltet Tasmota-Smart-Plugs ein und aus. -* **Statusanzeige:** Zeigt den aktuellen Status (Ein/Aus) der Tasmota-Steckdosen an. -* **Dynamische Socket-Verwaltung:** Verwaltet Tasmota-Steckdosen in einem Array, um das Hinzufügen weiterer Geräte zu vereinfachen. +## Architektur -## 3. Verwendete Technologien +``` +Browser (Angular SPA) + │ + │ GET /api/items/landingpage (kein Token im Frontend) + │ GET /api/assets/ + │ GET http://stecker1.neugasse.lan/cm?cmnd=Power + │ GET http://stecker2.neugasse.lan/cm?cmnd=Power + ▼ +Nginx Proxy Manager + │ injiziert: Authorization: Bearer → Directus + │ Tasmota-Geräte werden direkt vom Browser angesprochen (LAN) + ▼ +Nginx-Container (Port 9999) + └── dist/ (Angular Production Build) +``` -Das Projekt basiert auf dem Angular-Framework und verwendet eine Reihe von Bibliotheken und Tools: +Der Directus API-Token verlässt niemals den Browser — er wird ausschließlich im **Nginx Proxy Manager** als `proxy_set_header` konfiguriert. -* **Angular:** Version `^17.1.0` - * `@angular/animations` - * `@angular/common` - * `@angular/compiler` - * `@angular/core` - * `@angular/forms` - * `@angular/platform-browser` - * `@angular/platform-browser-dynamic` - * `@angular/router` -* **TypeScript:** Version `~5.3.2`, `^5.2 <5.4` -* **RxJS:** Für reaktive Programmierung, Version `^6.5.3 || ^7.4.0` (als Peer Dependency) und `7.8.1` (als Dependency in `@angular-devkit/build-webpack`). -* **Lodash:** Version `^4.14.202` (typings) und `^4.17.21` (dependency). -* **Webpack:** Version `5.89.0` -* **Node.js:** Empfohlene Versionen `^18.13.0 || >=20.9.0`. -* **npm:** Empfohlene Versionen `^6.11.0 || ^7.5.6 || >=8.0.0`. -* **Yarn:** Empfohlene Version `">= 1.13.0"`. +--- -## 4. Voraussetzungen +## Nginx Proxy Manager — Konfiguration -Stellen Sie sicher, dass Node.js und npm (oder Yarn) auf Ihrem System installiert sind. -* Node.js: `^18.13.0 || >=20.9.0` -* npm: `^6.11.0 || ^7.5.6 || >=8.0.0` -* Yarn: `>= 1.13.0` +Im Proxy Host der Landing Page unter **Advanced → Custom Nginx Configuration**: -## 5. Installation +```nginx +location /api/items/landingpage { + proxy_pass http://directus.neugasse.lan/items/landingpage; + proxy_set_header Authorization "Bearer "; + proxy_set_header Host directus.neugasse.lan; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +} -1. **Repository klonen:** - ```bash - git clone https://code.lonely-wolf.at/nas/new-landing-page-homenas.git - cd ang-university-httpclient - ``` -2. **Abhängigkeiten installieren:** - ```bash - npm install - # oder - yarn install - ``` - -## 6. Entwicklungsserver - -Führen Sie `ng serve` aus, um einen Entwicklungsserver zu starten. Die Anwendung wird automatisch im Browser unter `http://localhost:4200/` geöffnet. Änderungen am Quellcode werden automatisch neu geladen. - -Für die Entwicklungsumgebung wird eine Proxy-Konfiguration (`proxy.conf.json`) verwendet, um Anfragen an die Tasmota-Geräte weiterzuleiten. Diese Konfiguration ist Teil des Angular CLI-Dev-Servers und muss nicht manuell als separater Server eingerichtet werden. - -**`proxy.conf.json` Beispiel:** -```json -{ - "/tasmota1": { - "target": "http://10.0.0.31", - "secure": false, - "changeOrigin": true, - "pathRewrite": { - "^/tasmota1": "" - } - }, - "/tasmota2": { - "target": "http://10.0.0.32", - "secure": false, - "changeOrigin": true, - "pathRewrite": { - "^/tasmota2": "" - } - } +location /api/assets/ { + proxy_pass http://directus.neugasse.lan/assets/; + proxy_set_header Authorization "Bearer "; + proxy_set_header Host directus.neugasse.lan; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ``` -Diese Datei wird automatisch vom Angular Entwicklungsserver verwendet, wenn Sie `ng serve` ausführen. -## 7. Code-Struktur (Tasmota-Komponente) +--- -Die Tasmota-Steuerung ist modular aufgebaut: +## Deployment -* **`src/app/socket.interface.ts` (neu):** Definiert die Struktur für ein Tasmota-Socket-Objekt, das `id`, `name`, `path` und `status` enthält. -* **`src/app/tasmota.service.ts`:** Verantwortlich für die Kommunikation mit den Tasmota-Geräten. Es enthält ein Array von `TasmotaSocket`-Objekten (`public sockets`) und Methoden zum Abrufen des Status und zum Schalten der Steckdosen über HTTP-GET-Anfragen [Konversation]. Die `baseUrl` für Tasmota-Geräte ist in `environment.ts` und `environment.prod.ts` definiert. -* **`src/app/tasmota-control/tasmota-control.component.ts`:** Die Hauptkomponente, die die Tasmota-Steckdosen im UI darstellt. Sie iteriert über das `sockets`-Array des `TasmotaService`, um den Status anzuzeigen und Schaltvorgänge auszulösen [Konversation]. -* **`src/app/tasmota-control/tasmota-control.component.html`:** Das Template, das die einzelnen Steckdosen dynamisch rendert, basierend auf dem `sockets`-Array [Konversation]. +### Voraussetzungen -## 8. Build +- Node.js 20 LTS +- Angular CLI 17.x (`npm install -g @angular/cli`) +- Docker + Docker Compose auf dem Zielhost (Synology NAS) -Um das Projekt für die Produktion zu erstellen, führen Sie `ng build` aus. Die Build-Artefakte werden im Verzeichnis `dist/` gespeichert. +### Production Build -Für den Produktions-Build (`ng build --configuration production`) sind Optimierungen wie `outputHashing: "all"` aktiviert, während im Entwicklungs-Build (`ng build --configuration development`) Optimierungen deaktiviert und Source Maps enthalten sind. +```bash +# 1. Dependencies installieren (einmalig nach Clone) +npm install -## 9. Tests +# 2. Production Build +ng build -Um Unit-Tests mit Karma auszuführen, verwenden Sie den Befehl `ng test`. +# Output: dist/ang-university-httpclient/browser/ +``` -## 10. Konfiguration +### Deploy auf NAS -Die API-URLs für die Tasmota-Geräte werden in den Umgebungsvariablen-Dateien konfiguriert: +```bash +rsync -av --delete dist/ang-university-httpclient/browser/ \ + hans@nas.neugasse.lan:/volume1/docker/landingpage/dist/ +``` -* **`src/environments/environment.ts`:** Für die Entwicklungsumgebung. - ```typescript - export const environment = { - production: false, - apiUrl: 'http://10.0.0.104' // Beispiel-URL - }; - ``` -* **`src/environments/environment.prod.ts`:** Für die Produktionsumgebung. - ```typescript - export const environment = { - production: true, - apiUrl: '' // Leer lassen, wenn die App auf dem gleichen Server wie Tasmota läuft - }; - ``` +### Docker-Container starten -Die `.editorconfig`-Datei sorgt für konsistente Code-Formatierung im Team. Die `angular.json`-Datei enthält die Konfiguration für Angular CLI-Befehle und den Build-Prozess. +```bash +cd webserver-docker +docker compose up -d +``` -## 11. Hinweise zur Tasmota-Optimierung +Der Container lauscht auf Port `9999` und wird vom Nginx Proxy Manager nach außen exponiert. -Die Tasmota-Komponente kann weiter optimiert werden durch: -* **Minimierung von HTTP-Anfragen:** Implementierung eines Caching-Mechanismus oder eines gemeinsam genutzten Zustands im `TasmotaService`, um redundante Statusanfragen zu vermeiden. -* **Fehlerbehandlung:** Erweiterung der Fehlerbehandlung, um Benutzer über Probleme zu informieren oder Wiederholungsversuche bei Fehlern zu implementieren. -* **RxJS-Operatoren:** Nutzung weiterer RxJS-Operatoren wie `debounceTime` (für schnelle Toggle-Anfragen) oder `shareReplay` (für gemeinsame HTTP-Anfragen bei mehreren Abonnements) im `TasmotaService`. -* **Lazy Loading:** Wenn die Tasmota-Steuerung nicht beim initialen Laden der Anwendung benötigt wird, kann das zugehörige Modul per Lazy Loading geladen werden, um die anfängliche Ladezeit zu reduzieren. -* **Change Detection Strategy:** Verwendung der `OnPush`-Strategie für die `TasmotaControlComponent` zur Verbesserung der Performance. +--- + +## Lokale Entwicklung + +### Dev-Proxy einrichten + +`proxy.conf.json` wird nicht ins Repository committed (siehe `.gitignore`). +Vorlage kopieren und Token eintragen: + +```bash +cp proxy.conf.example.json proxy.conf.json +# Token eintragen +``` + +### Dev-Server starten + +```bash +ng serve +``` + +Der Proxy ist in `angular.json` unter `serve.options.proxyConfig` eingetragen und wird automatisch verwendet. + +--- + +## Tasmota-Steckdosen + +Die Steckdosen werden direkt vom Browser über ihre lokalen DNS-Namen angesprochen. +Konfiguration in `src/app/tasmota.service.ts`: + +| ID | Name | Adresse | +|---|---|---| +| 1 | Aktiv Kohle Lüfter | `http://stecker1.neugasse.lan` | +| 2 | Bambu P1P | `http://stecker2.neugasse.lan` | + +Weitere Steckdosen können im `sockets`-Array in `tasmota.service.ts` ergänzt werden. + +--- + +## Projektstruktur + +``` +├── src/ +│ ├── app/ +│ │ ├── links/ # Service-Karten-Komponente +│ │ ├── tasmota-control/ # Steckdosen-Toggle-Komponente +│ │ ├── links.service.ts # Directus API-Anbindung +│ │ ├── tasmota.service.ts # Tasmota HTTP-API +│ │ ├── links.ts # Interfaces: Links, LinksResponse +│ │ └── socket.interface.ts # Interface: TasmotaSocket +│ └── environments/ +│ ├── environment.ts # Dev +│ └── environment.prod.ts # Prod +├── webserver-docker/ +│ ├── docker-compose.yml # nginx:stable-alpine, Port 9999 +│ └── nginx.conf # SPA-Routing, Gzip, Cache-Header +├── proxy.conf.example.json # Dev-Proxy Vorlage (ohne Token) +└── apacheconfs/ # Veraltet — nicht mehr verwendet +``` + +> `apacheconfs/` ist historisch und wird nicht mehr aktiv genutzt. Der Reverse Proxy wird vollständig über den Nginx Proxy Manager abgebildet. + +--- + +## Sicherheitshinweise + +- Der Directus API-Token gehört **ausschließlich** in die NPM-Konfiguration — nie in den Quellcode oder ins Repository +- `proxy.conf.json` ist in `.gitignore` eingetragen und wird nicht committed +- Tasmota-Geräte sind nur im LAN erreichbar (`*.neugasse.lan`)