diff --git a/README.md b/README.md index 414a78b..35206c6 100644 --- a/README.md +++ b/README.md @@ -1,156 +1,93 @@ # Dashcam Transfer Automatisch dashcam-opnames (MP4) overzetten van een SD-kaart naar een USB-SSD, met -organisatie per datum en camera-positie (front/back). +organisatie per datum en camera-positie (front/back). Draait op de **nextcloud** server. -## Werking +## Architectuur -### Hardware setup +``` +SD-kaart insteken + → udev detecteert vendor:product (14cd:1212 of 05e3:0751) + → systemd-run start /usr/local/bin/dashcam-transfer-mount.sh + → wacht tot /dev/disk/by-uuid/00D3-7715 verschijnt (max 60s) + → mount UUID op /mnt/sdcard (uid=1000, exfat) + → systemctl start dashcam-transfer.service + → /usr/local/bin/dashcam-transfer.py + 1. Check mounts (/mnt/sdcard, /mnt/ultratouch) + 2. Scan /mnt/sdcard/Novatek/Movie/ op *.MP4 + 3. Check vrije ruimte — verwijder oudste datum-mappen indien nodig + 4. Copy + verify + delete per bestand + 5. Stuur WhatsApp notificatie via wwebjs-api +``` -| Component | Mount | Doel | -|---|---|---| -| USB-SSD (4TB) | `/mnt/ultratouch` | Opslag | -| SD-kaart (USB reader) | `/mnt/sdcard` | Bron | +## Hardware -Beide worden automatisch gemount via systemd automount units. +| Component | Mount | Device | Doel | +|---|---|---|---| +| USB-SSD (4TB, Seagate Ultra Touch) | `/mnt/ultratouch` | `/dev/disk/by-uuid/3027-8ECA` | Opslag | +| SD-kaart (via USB reader) | `/mnt/sdcard` | `/dev/disk/by-uuid/00D3-7715` | Bron | -### SD-kaart structuur (bron) +SSD wordt gemount via systemd `.automount` unit (permanent aangesloten). +SD-kaart wordt gemount door `dashcam-transfer-mount.sh` na udev trigger. -De Novatek dashcam slaat opnames op in de volgende structuur: +## Bestandsstructuur + +### SD-kaart (bron) ``` /mnt/sdcard/Novatek/Movie/ -├── 20260529085848_0003363F.MP4 ← front camera -├── 20260529085848_0003364B.MP4 ← back camera -├── 20260529090348_0003365F.MP4 -├── 20260529090348_0003366B.MP4 +├── 20260622050346_0000001F.MP4 ← front camera +├── 20260622050346_0000002B.MP4 ← back camera └── ... ``` -**Bestandsnaam conventie:** -``` -YYYYMMDDHHMMSS_.MP4 -``` -- `YYYYMMDDHHMMSS` — datum + tijd van opname -- `` — oplopend nummer -- ``: `F` = **front**, `B` = **back** -- Bestandsgrootte: ~381 MB per clip (~5 minuten) +Bestandsnaam: `YYYYMMDDHHMMSS_.MP4` +- `F` = front, `B` = back +- ~381 MB per clip (~5 minuten) -### SSD structuur (doel) - -Na transfer worden de bestanden georganiseerd in een uniforme structuur: +### SSD (doel) ``` /mnt/ultratouch/dashcam/ -└── YYYYMMDD/ ← datum uit bestandsnaam - ├── front/ ← bestanden met suffix F - │ ├── YYYYMMDDHHMMSS_1234567F.MP4 - │ └── ... - └── back/ ← bestanden met suffix B - ├── YYYYMMDDHHMMSS_1234567B.MP4 - └── ... +└── YYYYMMDD/ + ├── front/ + │ └── ...F.MP4 + └── back/ + └── ...B.MP4 ``` -## Het script +## WhatsApp notificatie -`dashcam-transfer.py` — Python 3 script (stdlib only, geen externe dependencies). - -### Stappenplan - -1. **Mount check** — controleert of `/mnt/sdcard` en `/mnt/ultratouch` gemount zijn -2. **Scan** — zoekt `.MP4` bestanden in `Novatek/Movie/` -3. **Ruimte check** — berekent totale benodigde ruimte en vergelijkt met vrije ruimte -4. **Ruimte maken** — als er te weinig ruimte is, worden de oudste datum-mappen op de - SSD verwijderd tot er genoeg ruimte is -5. **Transfer** — voor elk bestand: - - Kopieer naar `dashcam/YYYYMMDD/{front,back}/` - - Verifieer bestandsgrootte (bron vs doel) - - Verwijder bronbestand alleen bij succesvolle verificatie -6. **Logging** — elk bestand wordt gelogd met datum, tijd en status - -### Gebruik - -```bash -# Alle bestanden overzetten -/usr/local/bin/dashcam-transfer - -# Beperkt tot eerste N bestanden (handig voor testen) -/usr/local/bin/dashcam-transfer --limit 10 -``` - -### Logbestand +Na elke transfer stuurt het script een WhatsApp bericht naar de beheerder: ``` -/tmp/dashcam-transfer.log +✅ Dashcam transfer voltooid: 164 bestanden (56.8 GB) overgezet, geen fouten ``` -Voorbeeld: -``` -[2026-05-29 19:54:29] INFO Transfer voltooid: 303 ok, 0 fouten -[2026-05-29 19:54:29] INFO Overgezet: 20260529112143_0003403F.MP4 → 20260529/front/ (381203172 bytes) -``` +De API (`wwebjs-api`) draait als Docker container op nextcloud zelf: -## Herstructurering +| Config | Waarde | +|---|---| +| API endpoint | `http://localhost:3001/client/sendMessage/EdGpt` | +| Sessie | `EdGpt` | +| Ontvanger | `31620248011@c.us` (privé chat Eddy) | -Bestaande data op `/mnt/ultratouch/dashcam/` was oorspronkelijk inconsistent: -- 2025: mappen `chauffeur/` en `weg/` (oude dashcam) -- Begin 2026: platte bestanden (direct in datum-map) -- Vanaf maart 2026: mappen `front/` en `rear/` +De container: `docker-compose.yml` in `/home/aiaiaiaiagent/wwebjs-api/`. -Het `restructure.py` script heeft alle historische data omgezet naar de uniforme -`front/`/`back/` structuur. Hierbij zijn bestanden gesorteerd op basis van de -camera-suffix in de bestandsnaam. +## Service & triggers -## Automatisering - -### Architectuur - -``` -USB insert → udev detecteert vendor:product 14cd:1212 - → systemd-run start mount script (niet direct vanuit udev i.v.m. rechten) - → wacht tot /dev/disk/by-uuid/00D3-7715 verschijnt - → umount eventuele stale mounts - → mount UUID op /mnt/sdcard - → start dashcam-transfer service - → Python script kopieert MP4's naar SSD -``` - -**SD kaart wordt altijd op UUID gemount** — ongeacht USB poort. - -### Configuratiebestanden op de server - -#### `/etc/udev/rules.d/99-dashcam-trigger.rules` +### Udev rule (`/etc/udev/rules.d/99-dashcam-trigger.rules`) ```udev -# Super Top microSD reader ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*[0-9]", ENV{ID_VENDOR_ID}=="14cd", ENV{ID_MODEL_ID}=="1212", RUN+="/usr/bin/systemd-run --no-block --collect /usr/local/bin/dashcam-transfer-mount" -# Genesys Logic microSD reader ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*[0-9]", ENV{ID_VENDOR_ID}=="05e3", ENV{ID_MODEL_ID}=="0751", RUN+="/usr/bin/systemd-run --no-block --collect /usr/local/bin/dashcam-transfer-mount" ``` -`systemd-run` draait het script in systemd context (niet udev) — essentieel voor correcte `mount`/`umount` rechten. +### Mount script (`/usr/local/bin/dashcam-transfer-mount.sh`) -#### `/usr/local/bin/dashcam-transfer-mount` +Wacht tot de UUID beschikbaar is, unmount eventuele stale mounts, mount de SD-kaart en start de service. -```bash -#!/bin/bash -UUID=/dev/disk/by-uuid/00D3-7715 -logger -t dashcam-transfer Trigger: SD card detected -# Wacht tot UUID symlink beschikbaar is -for ((i=0; i<60; i++)); do - if [ -e "$UUID" ]; then break; fi - sleep 1 -done -# Verwijder stale mounts van eerdere USB-poort -while mountpoint -q /mnt/sdcard; do - umount /mnt/sdcard || break -done -# Mount via UUID (werkt ongeacht /dev/sdb1/sdd1/sde1) -mount "$UUID" /mnt/sdcard -o uid=1000,gid=1000,fmask=0000,dmask=0000 -systemctl start dashcam-transfer -``` - -#### `/etc/systemd/system/dashcam-transfer.service` +### Systemd service (`/etc/systemd/system/dashcam-transfer.service`) ```ini [Unit] @@ -163,20 +100,26 @@ ExecStart=/usr/local/bin/dashcam-transfer User=root ``` -#### `/etc/fstab` (SD card niet in fstab — wordt gemount door trigger) +### Logging -```ini -UUID=3027-8ECA /mnt/ultratouch exfat noauto,x-systemd.automount,uid=1000,gid=1000,dmask=0000,fmask=0000 0 0 -``` +Alle activiteit wordt gelogd naar `/tmp/dashcam-transfer.log` op nextcloud. -SSD wordt gemount via systemd automount (permanent aangesloten). - -### SD kaart UUID - -Bij format verandert de UUID. Om de juiste UUID te vinden: +## Handmatig gebruik ```bash -sudo blkid /dev/sdX1 +# Alle bestanden overzetten +/usr/local/bin/dashcam-transfer + +# Beperkt tot eerste N bestanden (testen) +/usr/local/bin/dashcam-transfer --limit 10 ``` -Update vervolgens de `UUID=...` variabele in `/usr/local/bin/dashcam-transfer-mount`. +## Ontwikkeling + +Lokale repo: `~/src/dashcam-transfer/` op Mac Mini. +Deployen naar nextcloud: + +```bash +scp dashcam-transfer.py aiaiaiaiagent@nextcloud:/tmp/ +ssh aiaiaiaiagent@nextcloud 'sudo -A cp /tmp/dashcam-transfer.py /usr/local/bin/dashcam-transfer' +``` diff --git a/dashcam-transfer.py b/dashcam-transfer.py index d5f1bfe..8279d80 100644 --- a/dashcam-transfer.py +++ b/dashcam-transfer.py @@ -105,7 +105,7 @@ def ensure_free_space(needed_bytes, target_base): logging.info("Ruimte vrijgemaakt: %d bytes door %d mappen", freed, len(removed)) -WHATSAPP_API = "http://100.97.199.84:3000/client/sendMessage/EdGpt" +WHATSAPP_API = "http://localhost:3001/client/sendMessage/EdGpt" # localhost = nextcloud server, niet Mac Mini! WHATSAPP_CHAT = "31620248011@c.us" diff --git a/docs/superpowers/plans/2026-06-07-whatsapp-notification.md b/docs/superpowers/plans/2026-06-07-whatsapp-notification.md index 671432a..50a1b09 100644 --- a/docs/superpowers/plans/2026-06-07-whatsapp-notification.md +++ b/docs/superpowers/plans/2026-06-07-whatsapp-notification.md @@ -4,7 +4,7 @@ **Goal:** Add a WhatsApp notification to the dashcam transfer script that sends a summary to admin Eddy after each transfer. -**Architecture:** A single `send_whatsapp_notification()` function is added to `dashcam-transfer.py`. It POSTs to the local wwebjs-api (running on Mac Mini via Tailscale) using stdlib `urllib.request`. Failures are logged but never crash the script. +**Architecture:** A single `send_whatsapp_notification()` function is added to `dashcam-transfer.py`. It POSTs to the local wwebjs-api (running as Docker container on nextcloud, port 3001) using stdlib `urllib.request`. Failures are logged but never crash the script. **Tech Stack:** Python 3 stdlib (`urllib.request`, `json`), wwebjs-api REST API @@ -25,7 +25,7 @@ Add `import json` and `import urllib.request` after the existing stdlib imports. Insert before `parse_args()` (after `ensure_free_space`): ```python -WHATSAPP_API = "http://100.97.199.84:3000/client/sendMessage/EdGpt" +WHATSAPP_API = "http://localhost:3001/client/sendMessage/EdGpt" WHATSAPP_CHAT = "31620248011@c.us"