# Buschauffeurswekker Android-wekker-app die wekkers **automatisch** zet op basis van het EBS-dienstrooster in de Nextcloud CalDAV-agenda **EBS-Diensten**. De wekker wekt zoals elke normale wekker-app (geluid, trillen, volledig scherm, snooze) — maar het wanneer wordt zelf bepaald uit de dienst van morgen. ## Werking Elke dag om **12:00** haalt de app de agenda van **morgen** op en zet daaruit de dienstaanvang. Die wordt **naar beneden afgerond op een heel kwartier**: | Aanvang dienst | Aangenomen aanvang | |---|---| | 05:00 – 05:14 | 05:00 | | 05:15 – 05:29 | 05:15 | | 05:30 – 05:44 | 05:30 | | 05:45 – 05:59 | 05:45 | Technisch: `minuut = (minuut / 15) * 15` (floor op kwartier). Rond middernacht kan de wekker op de vorige dag vallen (dienst 00:10 → Opstaan de dag ervoor 22:00). Daarna worden drie wekkers gezet, elk voor de afgeronde aanvang: | Wekker | Tijd vóór aanvang | Voorbeeld (06:15) | |---|---|---| | **Opstaan** | 2 uur | 04:15 | | **Wally** | 1,5 uur | 04:45 | | **Vertrek** | 0,5 uur | 05:45 | **Geen dienst morgen → geen wekkers.** ## Kenmerken - **Donkere wekker-UI** in de stijl van de systeemwekker: kop "Wekkers", één kaart per wekker met grote tijd + naam, acties achter het **⋮-menu**. - **Aan/uit per wekker** — schakelaar op elke kaart; een uitgezette wekker blijft uit (ook de dagelijkse 12:00-controle plant hem niet opnieuw) tot je hem weer aanzet. Uitgeschakelde kaart is grijs, aangezette blauw. - **Eigen geluid per wekker** via Instellingen → Wekkergeluiden (systeem-ringtone- kiezer). Standaard is het systeem-alarmgeluid; valt terug op die toon als het gekozen bestand verdwenen is. - **Volwaardige wekker**: geluid (herhalend) + trillen, volledig scherm óók bovenop het vergrendelscherm, snooze 10 min, "wekker uit". - **Werkt op de achtergrond**: exacte alarmen (ook in Doze), herstel na herstart, mobiele data toegestaan. - **Statusmelding om 12:00** met de wekkers van morgen; tikken opent de app. ## Schermen - **Hoofdscherm** — "Wekkers": de drie wekkerkaarten (met aan/uit) van morgen; onderaan de diensttijd ("Dienst om 06:18"). Het **⋮**-menu bevat *Nu controleren* en *Instellingen*. - **Instellingen** — CalDAV-gegevens (agenda-URL, gebruiker, app-wachtwoord + Opslaan) en *Wekkergeluiden* (per wekker een geluid). - **Afgaande wekker** — full-screen: naam, lopende klok, Snooze (10 min) / Wekker uit. ## Installatie 1. Bouw: `./gradlew :app:assembleDebug` → `app/build/outputs/apk/debug/app-debug.apk` 2. APK op de telefoon zetten en installeren (sideload). 3. App openen → **⋮ → Instellingen** → invullen: - Agenda-URL: `https://nextcloud.eddydevink.nl/remote.php/dav/calendars/eddy/ebs_diensten-1/` - Gebruikersnaam: `eddy` - App-wachtwoord: een Nextcloud-app-wachtwoord (Nextcloud → Beveiliging → App-wachtwoorden). Niet in de app hardcoden; zie de Obsidian-vault. 4. **Opslaan** → terug → **⋮ → Nu controleren** om te testen. 5. Meldingenmachtiging: systeemdialoog bij de eerste start. Config is ook zonder UI te zetten (installatiehulp): ```bash adb shell am start -n nl.eddydevink.buschauffeurswekker/.MainActivity \ --es url 'https://nextcloud.eddydevink.nl/remote.php/dav/calendars/eddy/ebs_diensten-1/' \ --es user 'eddy' --es pass '' ``` ## Machtigingen | Machtiging | Doel | |---|---| | Internet / netwerk | Agenda ophalen over wifi én mobiele data | | Meldingen (`POST_NOTIFICATIONS`) | Afgaande wekker + status tonen | | Exacte alarmen (`USE_EXACT_ALARM` / `SCHEDULE_EXACT_ALARM`) | Wekker óp tijd, ook in Doze | | Volledig scherm (`USE_FULL_SCREEN_INTENT`) | Wekker bovenop het vergrendelscherm | | Wakelock + trillen | Scherm aanhouden en trillen tijdens afgaan | | Boot (`RECEIVE_BOOT_COMPLETED`) | Wekkers + 12:00-controle na herstart herstellen | ## Architectuur ``` App kanalen + 12:00-controle bij opstart dagelijks 12:00 AlarmScheduler.scheduleNoonCheck (exact, allowWhileIdle) → DailyCheckReceiver → ShiftCheck.run CalDavClient REPORT calendar-query (time-range, basic auth) Ical iCal-parse: DTSTART (TZID/UTC), vroegste aanvang ShiftPlanner kwartier-afronding + Opstaan/Wally/Vertrek AlarmScheduler plan de aangezette wekkers afgaan AlarmScheduler.scheduleAlarm (exact, allowWhileIdle) → AlarmRingReceiver → full-screen intent + start → AlarmActivity Ringer geluid (loop; eigen keuze met fallback) + trillen snooze 10 min / dismiss MainActivity / SettingsActivity UI (kaarten, menu, instellingen, geluidskeuze) BootReceiver na reboot: wekkers + 12:00-controle herstellen Prefs instellingen/status/plan, versleuteld (EncryptedSharedPreferences) ``` ### Modules - `core/ShiftPlanner.kt` — pure logica: kwartier-afronding + wekkerplanning (JVM-tests). - `caldav/Ical.kt` — minimale RFC 5545-parser (VEVENT, DTSTART met TZID/UTC; all-day en geannuleerde events worden overgeslagen). - `caldav/CalDavClient.kt` — REPORT calendar-query (recept uit de scrapedienst). - `core/ShiftCheck.kt` — orchestrator: ophalen → filteren op morgen → vroegste aanvang → plannen (aangezette) of annuleren; gedeeld door receiver, menu-knop en setup-intent. - `core/AlarmScheduler.kt` — exacte alarmen, 12:00-controle, snooze, per-naam aanv/uit. - `core/Notifier.kt` — kanalen "wekkers"/"status"; statusmelding tikt de app open. - `core/Ringer.kt` — wekkergeluid (loop) gekozen per wekker + vibratie; fallback naar de standaard alarmtoon als het gekozen bestand weg is. - `receivers/DailyCheckReceiver.kt`, `AlarmRingReceiver.kt`, `BootReceiver.kt`. - `AlarmActivity.kt` — full-screen wekker (geluid, trillen, snooze/dismiss). - `SettingsActivity.kt` — CalDAV-gegevens + per-wekker geluidskeuze. ## Keuzes - **12:00-controle = exact AlarmManager-alarm**, niet WorkManager: precies om 12:00 (WorkManager-periodiek is minimaal 15 min en onnauwkeurig). - Meerdere events op één dag → **vroegste aanvang** telt als dienstaanvang. - **All-day-events** ("vrij") tellen niet; alleen getimede diensten. - Na een fout (bv. offline) blijven eerder geplande wekkers staan + statusmelding. - Wachtwoord **versleuteld** op het toestel (EncryptedSharedPreferences AES256-GCM; bij falen plain fallback in de app-sandbox). Nooit hardcoded. - UI volgt Material 3: donker thema, standaard `MaterialSwitch` en systeemcomponenten. ## Build & test - Gradle wrapper 8.13 · AGP 8.7.3 · Kotlin 2.0.21 - compileSdk/targetSdk 34, minSdk 27 (Android 8.1+) - `./gradlew :app:assembleDebug` en `./gradlew :app:testDebugUnitTest` - Unit tests dekken de afrondingsvoorbeelden (incl. de vier óf), wekkerplanning, iCal-parse en een snapshot van een echte serverresponse door de pipeline. ## Gerelateerd - **Scrapedienst** — vult de `ebs_diensten`-agenda (dagelijks 17:05): `~/src/scrapedienst` + vault-notitie `Homelab/Software ontwikkeling/scrapedienst.md` - **CalDAV-referentieclient**: `~/src/caldav-mcp` - **Meldingen/wekkers** staan uit; zie de Obsidian-vault-notitie `Homelab/Software ontwikkeling/Buschauffeurswekker.md`