7 KiB
7 KiB
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
- Bouw:
./gradlew :app:assembleDebug→app/build/outputs/apk/debug/app-debug.apk - APK op de telefoon zetten en installeren (sideload).
- 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.
- Agenda-URL:
- Opslaan → terug → ⋮ → Nu controleren om te testen.
- Meldingenmachtiging: systeemdialoog bij de eerste start.
Config is ook zonder UI te zetten (installatiehulp):
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 '<app-wachtwoord>'
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
MaterialSwitchen 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:assembleDebugen./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-notitieHomelab/Software ontwikkeling/scrapedienst.md - CalDAV-referentieclient:
~/src/caldav-mcp - Meldingen/wekkers staan uit; zie de Obsidian-vault-notitie
Homelab/Software ontwikkeling/Buschauffeurswekker.md