README: volledige herschrijving (schermen, features, installatie, architectuur)
This commit is contained in:
parent
a14ede3b8c
commit
7f470e4505
1 changed files with 123 additions and 91 deletions
208
README.md
208
README.md
|
|
@ -1,123 +1,155 @@
|
||||||
# Buschauffeurswekker
|
# Buschauffeurswekker
|
||||||
|
|
||||||
Android-app die de functie van de normale wekker-app vervult, maar de wekkers
|
Android-wekker-app die wekkers **automatisch** zet op basis van het EBS-dienstrooster
|
||||||
automatisch zet op basis van de Nextcloud CalDAV-agenda **EBS-Diensten**.
|
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
|
## Werking
|
||||||
|
|
||||||
- Elke dag om **12:00** leest de app de agenda van de **volgende dag**.
|
Elke dag om **12:00** haalt de app de agenda van **morgen** op en zet daaruit de
|
||||||
- De dienstbegintijd wordt **naar beneden afgerond op een heel kwartier**:
|
dienstaanvang. Die wordt **naar beneden afgerond op een heel kwartier**:
|
||||||
- 05:00–05:14 → 05:00
|
|
||||||
- 05:15–05:29 → 05:15
|
| Aanvang dienst | Aangenomen aanvang |
|
||||||
- 05:30–05:44 → 05:30
|
|---|---|
|
||||||
- 05:45–05:59 → 05:45
|
| 05:00 – 05:14 | 05:00 |
|
||||||
- Er worden drie wekkers gezet, alle drie vóór de afgeronde aanvangstijd:
|
| 05:15 – 05:29 | 05:15 |
|
||||||
- **Opstaan** — 2 uur vóór aanvang
|
| 05:30 – 05:44 | 05:30 |
|
||||||
- **Wally** — 1,5 uur vóór aanvang
|
| 05:45 – 05:59 | 05:45 |
|
||||||
- **Vertrek** — 0,5 uur vóór aanvang
|
|
||||||
- Staat er **geen dienst** in de agenda voor morgen, dan worden **geen wekkers** gezet.
|
Technisch: `minuut = (minuut / 15) * 15` (floor op kwartier). Rond middernacht kan de
|
||||||
- Per wekker is een **aan/uit-schakelaar** op het hoofdscherm: uitgezet blijft uit
|
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.
|
(ook de dagelijkse 12:00-controle plant hem niet opnieuw) tot je hem weer aanzet.
|
||||||
- In **Instellingen → Wekkergeluiden** kun je per wekker een eigen geluid kiezen
|
Uitgeschakelde kaart is grijs, aangezette blauw.
|
||||||
via de systeem-ringtone-kiezer; standaard is het systeem-alarmgeluid.
|
- **Eigen geluid per wekker** via Instellingen → Wekkergeluiden (systeem-ringtone-
|
||||||
- De wekker gaat volwaardig af (geluid + trillen, volledig scherm) **ook bij een
|
kiezer). Standaard is het systeem-alarmgeluid; valt terug op die toon als het
|
||||||
vergrendeld scherm**, met snooze (10 min) en "wekker uit".
|
gekozen bestand verdwenen is.
|
||||||
- Het toestel mag daarvoor **mobiele data** verbruiken en taken op de
|
- **Volwaardige wekker**: geluid (herhalend) + trillen, volledig scherm óók bovenop
|
||||||
**achtergrond** uitvoeren.
|
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
|
## Installatie
|
||||||
|
|
||||||
1. Bouw de APK: `./gradlew :app:assembleDebug`
|
1. Bouw: `./gradlew :app:assembleDebug`
|
||||||
→ `app/build/outputs/apk/debug/app-debug.apk`
|
→ `app/build/outputs/apk/debug/app-debug.apk`
|
||||||
2. Zet de APK op de telefoon en installeer (sideload).
|
2. APK op de telefoon zetten en installeren (sideload).
|
||||||
3. Open de app → **Instellingen** → vul in:
|
3. App openen → **⋮ → Instellingen** → invullen:
|
||||||
- Agenda-URL: `https://nextcloud.eddydevink.nl/remote.php/dav/calendars/eddy/ebs_diensten-1/`
|
- Agenda-URL: `https://nextcloud.eddydevink.nl/remote.php/dav/calendars/eddy/ebs_diensten-1/`
|
||||||
- Gebruikersnaam: `eddy`
|
- Gebruikersnaam: `eddy`
|
||||||
- App-wachtwoord: een Nextcloud-app-wachtwoord
|
- App-wachtwoord: een Nextcloud-app-wachtwoord (Nextcloud → Beveiliging →
|
||||||
(Nextcloud → Beveiliging → App-wachtwoorden; zie de Obsidian-vault voor
|
App-wachtwoorden). Niet in de app hardcoden; zie de Obsidian-vault.
|
||||||
de bestaande app-wachtwoorden — niet in de app hardcoden)
|
4. **Opslaan** → terug → **⋮ → Nu controleren** om te testen.
|
||||||
4. **Opslaan**, terug op het hoofdscherm **Nu controleren** om te testen.
|
5. Meldingenmachtiging: systeemdialoog bij de eerste start.
|
||||||
5. Verleen de meldingenmachtiging bij de eerste start (systeemdialoog).
|
|
||||||
|
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 '<app-wachtwoord>'
|
||||||
|
```
|
||||||
|
|
||||||
## Machtigingen
|
## Machtigingen
|
||||||
|
|
||||||
| Machtiging | Doel |
|
| Machtiging | Doel |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Internet / netwerk | Agenda ophalen over wifi én mobiele data |
|
| Internet / netwerk | Agenda ophalen over wifi én mobiele data |
|
||||||
| Meldingen (POST_NOTIFICATIONS) | Afgaande wekker tonen |
|
| Meldingen (`POST_NOTIFICATIONS`) | Afgaande wekker + status tonen |
|
||||||
| Exacte alarmen (USE_EXACT_ALARM / SCHEDULE_EXACT_ALARM) | Wekker óp tijd, ook in Doze |
|
| Exacte alarmen (`USE_EXACT_ALARM` / `SCHEDULE_EXACT_ALARM`) | Wekker óp tijd, ook in Doze |
|
||||||
| Volledig scherm (USE_FULL_SCREEN_INTENT) | Wekker bovenop het vergrendelscherm |
|
| Volledig scherm (`USE_FULL_SCREEN_INTENT`) | Wekker bovenop het vergrendelscherm |
|
||||||
| Wakelock + trillen | Scherm aanhouden en trillen tijdens afgaan |
|
| Wakelock + trillen | Scherm aanhouden en trillen tijdens afgaan |
|
||||||
| Boot (RECEIVE_BOOT_COMPLETED) | Wekkers na herstart opnieuw inplannen |
|
| Boot (`RECEIVE_BOOT_COMPLETED`) | Wekkers + 12:00-controle na herstart herstellen |
|
||||||
| Batterijoptimalisatie uitzonderen | Achtergrondtaken betrouwbaar |
|
|
||||||
|
|
||||||
## Architectuur
|
## Architectuur
|
||||||
|
|
||||||
```
|
```
|
||||||
MainActivity hoofdscherm: klok + geplande wekkers + "Nu controleren" + link naar instellingen
|
App kanalen + 12:00-controle bij opstart
|
||||||
SettingsActivity instellingen: CalDAV-url, gebruiker, app-wachtwoord (+ uitleg)
|
|
||||||
AlarmActivity volledig-scherm wekker (geluid, trillen, snooze/dismiss)
|
dagelijks 12:00
|
||||||
App kanalen + dagelijkse 12:00-controle bij opstart
|
AlarmScheduler.scheduleNoonCheck (exact, allowWhileIdle)
|
||||||
daily check:
|
→ DailyCheckReceiver → ShiftCheck.run
|
||||||
AlarmScheduler.scheduleNoonCheck → DailyCheckReceiver (12:00, exact, allowWhileIdle)
|
CalDavClient REPORT calendar-query (time-range, basic auth)
|
||||||
→ ShiftCheck.run agenda morgen ophalen → afronden → wekkers plannen
|
Ical iCal-parse: DTSTART (TZID/UTC), vroegste aanvang
|
||||||
→ CalDavClient REPORT calendar-query (time-range, basic auth)
|
ShiftPlanner kwartier-afronding + Opstaan/Wally/Vertrek
|
||||||
→ Ical iCal-parse: DTSTART (TZID/UTC), vroegste aanvang
|
AlarmScheduler plan de aangezette wekkers
|
||||||
→ ShiftPlanner afronding op kwartier + Opstaan/Wally/Vertrek
|
|
||||||
ring:
|
afgaan
|
||||||
AlarmScheduler.scheduleAlarm → AlarmRingReceiver (exact, allowWhileIdle)
|
AlarmScheduler.scheduleAlarm (exact, allowWhileIdle)
|
||||||
→ full-screen intent + directe start → AlarmActivity
|
→ AlarmRingReceiver → full-screen intent + start → AlarmActivity
|
||||||
→ Ringer wekkergeluid (loop) + vibratiepatroon
|
Ringer geluid (loop; eigen keuze met fallback) + trillen
|
||||||
BootReceiver na reboot: 12:00-controle + geplande wekkers herstellen
|
snooze 10 min / dismiss
|
||||||
Prefs instellingen/status, versleuteld (EncryptedSharedPreferences)
|
|
||||||
|
MainActivity / SettingsActivity UI (kaarten, menu, instellingen, geluidskeuze)
|
||||||
|
BootReceiver na reboot: wekkers + 12:00-controle herstellen
|
||||||
|
Prefs instellingen/status/plan, versleuteld (EncryptedSharedPreferences)
|
||||||
```
|
```
|
||||||
|
|
||||||
Hoofdscherm en instellingen zijn bewust gescheiden; installatiehulp via
|
### Modules
|
||||||
launch-intent-extra's (`--es url/user/pass`) slaat de config op en draait
|
|
||||||
direct een controle, zonder UI-interactie.
|
|
||||||
|
|
||||||
Details per bestand:
|
- `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
|
||||||
- `core/ShiftPlanner.kt` — pure logica: kwartier-afronding en wekkerplanning
|
geannuleerde events worden overgeslagen).
|
||||||
(JVM-unit-tests, geen Android-afhankelijkheden).
|
- `caldav/CalDavClient.kt` — REPORT calendar-query (recept uit de scrapedienst).
|
||||||
- `caldav/Ical.kt` — minimale RFC 5545-parser (VEVENT, DTSTART met TZID/UTC,
|
- `core/ShiftCheck.kt` — orchestrator: ophalen → filteren op morgen → vroegste aanvang
|
||||||
all-day en geannuleerde events worden overgeslagen).
|
→ plannen (aangezette) of annuleren; gedeeld door receiver, menu-knop en setup-intent.
|
||||||
- `caldav/CalDavClient.kt` — REPORT calendar-query volgens het recept van de
|
- `core/AlarmScheduler.kt` — exacte alarmen, 12:00-controle, snooze, per-naam aanv/uit.
|
||||||
scrapedienst (zie vault-notitie `Homelab/Software ontwikkeling/scrapedienst.md`).
|
- `core/Notifier.kt` — kanalen "wekkers"/"status"; statusmelding tikt de app open.
|
||||||
- `core/ShiftCheck.kt` — orchestrator: ophalen → filteren op morgen → vroegste
|
- `core/Ringer.kt` — wekkergeluid (loop) gekozen per wekker + vibratie; fallback naar
|
||||||
aanvang → plannen of annuleren; gedeeld door receiver en knop.
|
de standaard alarmtoon als het gekozen bestand weg is.
|
||||||
- `core/AlarmScheduler.kt` — exacte alarmen + 12:00-controle + snooze + testwekker.
|
- `receivers/DailyCheckReceiver.kt`, `AlarmRingReceiver.kt`, `BootReceiver.kt`.
|
||||||
- `receivers/DailyCheckReceiver.kt` — 12:00; plant zichzelf via AlarmScheduler
|
- `AlarmActivity.kt` — full-screen wekker (geluid, trillen, snooze/dismiss).
|
||||||
steeds opnieuw.
|
- `SettingsActivity.kt` — CalDAV-gegevens + per-wekker geluidskeuze.
|
||||||
- `receivers/AlarmRingReceiver.kt` — afgaande wekker: wakelock, full-screen
|
|
||||||
intent (ook vergrendeld scherm), directe activity-start.
|
|
||||||
- `receivers/BootReceiver.kt` — herstart-herstel (BOOT_COMPLETED, TIME_SET,
|
|
||||||
TIMEZONE_CHANGED, MY_PACKAGE_REPLACED).
|
|
||||||
- `core/Notifier.kt`, `core/Ringer.kt` — meldingen (kanalen "wekkers"/"status")
|
|
||||||
en geluid/trillen.
|
|
||||||
|
|
||||||
## Keuzes
|
## Keuzes
|
||||||
|
|
||||||
- **12:00-controle via exact AlarmManager-alarm**, niet WorkManager: precies om
|
- **12:00-controle = exact AlarmManager-alarm**, niet WorkManager: precies om 12:00
|
||||||
12:00 (WorkManager periodiek is minimaal 15 min en onnauwkeurig).
|
(WorkManager-periodiek is minimaal 15 min en onnauwkeurig).
|
||||||
- Bij **meerdere events** op één dag geldt de **vroegste aanvang** als
|
- Meerdere events op één dag → **vroegste aanvang** telt als dienstaanvang.
|
||||||
dienstbegintijd.
|
- **All-day-events** ("vrij") tellen niet; alleen getimede diensten.
|
||||||
- **All-day-events** (bijv. "vrij") worden genegeerd; alleen getimede diensten
|
- Na een fout (bv. offline) blijven eerder geplande wekkers staan + statusmelding.
|
||||||
tellen.
|
- Wachtwoord **versleuteld** op het toestel (EncryptedSharedPreferences AES256-GCM;
|
||||||
- Na een fout (bv. offline) blijven eerder geplande wekkers staan en verschijnt
|
bij falen plain fallback in de app-sandbox). Nooit hardcoded.
|
||||||
een statusmelding.
|
- UI volgt Material 3: donker thema, standaard `MaterialSwitch` en systeemcomponenten.
|
||||||
- Wachtwoord staat **versleuteld** op het toestel
|
|
||||||
(EncryptedSharedPreferences, AES256-GCM; bij falen plain fallback in de
|
|
||||||
app-sandbox).
|
|
||||||
|
|
||||||
## Build
|
## Build & test
|
||||||
|
|
||||||
- Gradle wrapper 8.13, AGP 8.7.3, Kotlin 2.0.21
|
- Gradle wrapper 8.13 · AGP 8.7.3 · Kotlin 2.0.21
|
||||||
- compileSdk/targetSdk 34, minSdk 27 (Android 8.1+)
|
- compileSdk/targetSdk 34, minSdk 27 (Android 8.1+)
|
||||||
- Tests: `./gradlew :app:testDebugUnitTest`
|
- `./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
|
## Gerelateerd
|
||||||
|
|
||||||
- Scrapedienst die de EBS-Diensten-agenda vult:
|
- **Scrapedienst** — vult de `ebs_diensten`-agenda (dagelijks 17:05):
|
||||||
`~/src/scrapedienst` + vault-notitie `scrapedienst.md`
|
`~/src/scrapedienst` + vault-notitie `Homelab/Software ontwikkeling/scrapedienst.md`
|
||||||
- CalDAV-referentieclient: `~/src/caldav-mcp`
|
- **CalDAV-referentieclient**: `~/src/caldav-mcp`
|
||||||
|
- **Meldingen/wekkers** staan uit; zie de Obsidian-vault-notitie
|
||||||
|
`Homelab/Software ontwikkeling/Buschauffeurswekker.md`
|
||||||
Loading…
Reference in a new issue