Files
SaschaandClaude Opus 5 acb840bd0a Web-GUI auf Port 80 (ohne Portnummer aufrufbar)
Die Unit startet Node als User=callrec (uid 1000) und konnte darum keinen
privilegierten Port binden - daher bisher :3000. Mit
AmbientCapabilities=CAP_NET_BIND_SERVICE bindet der unprivilegierte Prozess
jetzt Port 80 direkt, ohne Reverse-Proxy (nginx haette 20-40 MB RAM gekostet,
die neben dem residenten rkllm nicht frei sind). Kein Code-Eingriff noetig:
server.js liest process.env.PORT, das Frontend nutzt relative API-Pfade.
:3000 ist bewusst tot, alte Lesezeichen muessen angepasst werden.

Dazu: Doku-IPs auf aime.local/192.168.1.48 korrigiert (192.168.1.200 war
veraltet) und die Geisteranzeige-Diagnose vom 26.08. in Kapitel 03 + Changelog
festgehalten (verwaister Browser-Reiter zaehlt ewig weiter, fmt() ohne Stunden).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 08:53:14 +02:00

86 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Aime — Dokumentation
> **Name:** Das Projekt heißt **Aime** (wie der Bluetooth-Name des Boards; vormals „CallRec“).
> Technische Bezeichner auf dem Board bleiben aus Stabilitätsgründen unverändert: `callrec.service`,
> `/opt/callrec`, DB/User `callrec`, PipeWire-Quelle „CallRecMix“.
Selbst gehostete Anruf-Aufnahme- und Analyse-Appliance auf einem **Youyeetoo R1 (RK3588S)** Einplatinenrechner.
Nimmt Gespräche auf (PC/Teams über USB-Gadget **und** iPhone über Bluetooth-HFP), transkribiert mit Whisper
(Encoder auf der NPU), trennt Sprecher akustisch (Diarization + Stimm-Profile) und erzeugt eine strukturierte
KI-Zusammenfassung (Gemma-3-4B auf der NPU) — **komplett offline**, keine Cloud.
## Inhaltsverzeichnis
| Dokument | Inhalt |
|---|---|
| [01 – Hardware](docs/01-hardware.md) | Board, Audio-Hardware, USB-Gadget, Thermik, NPU |
| [02 – Audio-Topologie](docs/02-audio-topologie.md) | PipeWire-Graph: callmix, Loopbacks, Noise-Gate, Volume-Bridges |
| [03 – Aufnahme-Pipeline](docs/03-aufnahme-pipeline.md) | Aufnahme → Transkription → Diarization → LLM → Datenbank |
| [04 – Sprechertrennung](docs/04-diarization.md) | Diarization, Anchor-Merge-Konsolidierung, Stimm-Profile |
| [05 – LLM-Analyse](docs/05-llm-analyse.md) | Gemma-3-4B/NPU, Analyse-Pfade, strukturierte Zusammenfassung, Glossar |
| [06 – iPhone-Bluetooth](docs/06-iphone-bt.md) | HFP-Pfad, Routing-Watcher, Echo-Fix |
| [07 – Betrieb](docs/07-betrieb.md) | Services, Zugänge, Backups, Troubleshooting |
| [08 – Changelog](docs/08-changelog.md) | Chronik aller Entwicklungsschritte |
| [09 – Suche & Verwaltung](docs/09-suche-und-verwaltung.md) | Inhaltssuche mit Zeitstempel-Verweis, Papierkorb, Titel umbenennen |
| [10 – Projektansicht](docs/10-projektansicht.md) | Projektordner, Unterreiter, angeheftete Aufnahmen |
## System-Überblick
```mermaid
flowchart LR
subgraph Quellen
PC["Windows-PC<br/>(Teams, Medien)"]
IPHONE["iPhone<br/>(Telefonate)"]
USER(("Nutzer<br/>Logi H390 Headset"))
end
subgraph R1["Youyeetoo R1 (RK3588S, Armbian, lüfterlos)"]
PW["PipeWire<br/>Audio-Routing<br/>(callmix + micgate)"]
APP["Aime Web-App<br/>Node.js :80"]
WH["Whisper large-v3-turbo<br/>Encoder auf NPU"]
DIAR["Diarization<br/>sherpa-onnx + TitaNet"]
LLM["Gemma-3-4B<br/>rkllm auf NPU"]
DB[("MariaDB<br/>callrec")]
end
PC -- "USB-C (UAC2-Gadget)" --> PW
IPHONE -- "Bluetooth HFP (AX210)" --> PW
USER -- "USB-A" --> PW
PW -- "callrec_mix" --> APP
APP --> WH --> DIAR --> LLM --> DB
APP --- DB
```
## Quick Facts
- **Board:** `aime.local` per mDNS — aktuell `192.168.1.48` (WLAN, DHCP) / `192.168.1.50` (LAN, statisch, nur bei gestecktem Kabel), Login `root`
- **Web-GUI:** `http://aime.local` — Port **80**, also ohne Portnummer im Browser. Aufnahme, Transkript, Sprecher-Editor, Glossar
- **App-Verzeichnis:** `/opt/callrec` (Node.js, systemd `callrec.service`)
- **Harte Anforderungen:** immer offline (kein Cloud-LLM), akustische Sprecher-ID, kein aktiver Lüfter
- Details und alle Zugangsdaten: [07 – Betrieb](docs/07-betrieb.md)
## Repo-Aufbau
| Verzeichnis | Inhalt |
|---|---|
| `app/` | Spiegel von **`/opt/callrec`** auf dem Board: Node-Backend (`server.js`, `recorder.js`, `llm.js`, `diar.js`, `spk.js`, `db.js`, `bt.js`), Vite-Frontend (`web/`), Python-Inferenz (`inference/`), Audio-/Setup-Skripte (`aime-*.sh`), `rkllm_server.cpp` |
| `system/` | System-Konfiguration, Pfade wie auf dem Board: systemd-Units (`etc/systemd/system/`, `home/callrec/.config/systemd/user/`), WirePlumber-Drop-ins, micgate-Filter-Chain, sudoers |
| `docs/` | Diese Dokumentation |
**Nicht im Repo** (zu groß / Laufzeit-Artefakte): `node_modules`, `web/dist` (per `npx vite build` erzeugbar),
Modelle (`*.rkllm`, `*.rknn`, `models/`), `rkllm_server`-Binary (aus `rkllm_server.cpp` kompilierbar),
Aufnahmen, `milestones/`, `.bak-*`.
**Restore-Hinweis:** `app/` → `/opt/callrec`, `system/…` → jeweilige Absolutpfade; danach `npm install`
(Root + `web/`), `npx vite build` in `web/`, User-Units mit `systemctl --user enable` aktivieren
(`filter-chain.service` maskieren!), Details in [07 – Betrieb](docs/07-betrieb.md).
⚠️ Das Repo ist die **Kopie** — die **Wahrheit läuft auf dem Board**. Nach jeder Board-Änderung Code hierher zurückspiegeln.
## Doku-Regeln
- Diese Doku ist die **verbindliche Ablage** für alle zukünftigen Änderungen am System.
- Jede Änderung: betroffenes Kapitel aktualisieren **und** Eintrag in [08 – Changelog](docs/08-changelog.md).
- Prozesse/Abläufe immer mit **Mermaid-Diagramm** dokumentieren (Gitea rendert sie direkt).
- Auf dem Board bleiben `.bak-*`-Dateien als Rollback-Punkte; Meilenstein-Snapshots unter `/opt/callrec/milestones/`.