# P2000Dashboard

Een Windows-desktopapplicatie voor het live volgen van P2000-hulpdiensten-pagerberichten
(ambulance/brandweer/politie): ontvangen, filteren, verrijken (voertuigen, termen, regio,
geocoding) en tonen in een grid en op een kaart, met optionele spraak-alarmering en
Home Assistant-integratie via MQTT. Bij het aanklikken van een incident toont het
"Tijdlijn incident"-tabblad eerdere/latere meldingen op dezelfde locatie (bijv. een brand
die escaleert van klein naar middel/grote/zeer grote brand, of GRIP-opschaling).

`PdwBridge` is een losstaande companion-executable die de output van een PDW-pagerdecoder
(seriële poort of command-file) uitleest en doorstuurt naar `P2000Dashboard.exe` via TCP of
seriële poort.

## Vereisten

- .NET 10 SDK/runtime (Windows), voor het bouwen/draaien van beide `.exe`'s.
- Een PDW-pagerdecoder (bijv. gevoed door een RTL-SDR/Airspy op 169.500 MHz) die berichten
  wegschrijft die door `PdwBridge` gelezen kunnen worden.
- Optioneel: **[edge-tts](https://github.com/rany2/edge-tts)**, geïnstalleerd en op PATH, als
  je gesproken alarmering wilt (bv. `pip install edge-tts`). Zonder deze tool — en met
  `TtsEnabled` op `false`, de standaard — blijft de app gewoon stil; gesproken meldingen zijn
  volledig optioneel. De gebruikte stem (`nl-NL-ColetteNeural`) is momenteel vast ingesteld,
  niet configureerbaar.
- Optioneel: een MQTT-broker, als je incidenten wilt doorpublicaten (bijv. naar Home Assistant).

## Configuratie

`PdwBridge.exe` en `P2000Dashboard.exe` zijn twee losse processen en hebben **elk hun eigen**
`appsettings.json`, die naast de gecompileerde `.exe` in de build-outputmap moet staan.

### P2000Dashboard

Bij de eerste start, als er nog geen `appsettings.json` bestaat, verschijnt automatisch een
setup-schermpje voor de instellingen die een echte keuze vergen (PDW-verbinding, MQTT,
gesproken meldingen) en schrijft dat bestand voor je weg. "Later instellen" mag ook — de app
draait dan met de defaults (alles optioneels uit) en de wizard verschijnt de volgende keer
gewoon weer.

Wil je het liever met de hand doen: kopieer `P2000Dashboard/appsettings.example.json` naar
`appsettings.json` (zelfde map) en vul je eigen waarden in. Dit bestand staat in `.gitignore`
omdat het geheimen (MQTT-wachtwoord) kan bevatten — commit het dus nooit.

| Key | Type | Omschrijving |
|---|---|---|
| `MqttEnabled` | bool | Publiceer incidenten naar MQTT (bv. voor Home Assistant). Standaard uit — volledig optioneel. |
| `MqttHost` | string | Hostnaam/IP van de MQTT-broker. |
| `MqttPort` | int | MQTT-broker poort (standaard 1883). |
| `MqttUsername` | string | MQTT-gebruikersnaam (leeg = geen authenticatie). |
| `MqttPassword` | string | MQTT-wachtwoord. |
| `MqttClientId` | string | MQTT client-id. |
| `MqttTopic` | string | MQTT-topic waarop incidenten gepubliceerd worden. |
| `UseTcpBridge` | bool | `true` = verbind met `PdwBridge.exe` via TCP; `false` = lees direct van een seriële COM-poort (kies in de UI). |
| `TcpHost` | string | Hostnaam/IP van de machine waarop `PdwBridge.exe` draait. |
| `TcpPort` | int | TCP-poort waarop `PdwBridge.exe` luistert. |
| `WatchdogEnabled` | bool | Actieve melding (geluid + knipperende statusbalk) als er te lang geen watchdog-capcode (`1180000`) binnenkomt. Standaard aan, maar heeft alleen effect als je dat capcode ook daadwerkelijk via PDW doorstuurt — doe je dat niet, dan gebeurt er sowieso niets. |
| `TtsEnabled` | bool | Spreek nieuwe golden/critical-meldingen uit via edge-tts. Standaard uit — vereist edge-tts apart geïnstalleerd, zie Vereisten. |
| `NominatimBaseUrl` | string | Nominatim search-endpoint (wijs naar je eigen instantie om de publieke rate-limit te vermijden). |
| `NominatimAppName` / `NominatimAppVersion` | string | Gebruikt om de User-Agent-header op te bouwen. |
| `NominatimContactEmail` | string | Contact-e-mailadres, verplicht volgens het gebruiksbeleid van Nominatim. |
| `StartupHistoryLimit` | int | Aantal recente incidenten dat bij opstarten uit de database in het grid geladen wordt (standaard 200). |
| `TimelineWindowHours` | int | Hoeveel uur tussen twee meldingen op dezelfde locatie nog als één doorlopende inzet wordt beschouwd in het "Tijdlijn incident"-tabblad (standaard 12). |

### PdwBridge

`PdwBridge/appsettings.json` bevat geen geheimen en staat al met veilige defaults in de repo.
Pas naar wens aan: `EnableTcpServer`/`EnableSerial` (kies precies één van beide), `ComPort`,
`BaudRate`, `TcpPort`, etc.

## Draaien

1. Bouw de solution: `dotnet build P2000Dashboard.slnx`.
2. Start `P2000Dashboard.exe`. Gebruik je TCP-modus, dan hoef je `PdwBridge.exe` niet apart te
   starten — die start zichzelf op zodra PDW voor het eerst een gefilterd bericht doorgeeft, en
   de TCP-verbinding vanuit P2000Dashboard blijft gewoon opnieuw proberen tot dat gebeurd is.

## Updaten

Een release bevat `defaultP2000Dashboard.db` (basisvulling: capcodes/places/terms/vehicles),
nooit `P2000Dashboard.db` zelf. Bij de allereerste start hernoemt de app dat bestand naar
`P2000Dashboard.db`; bestaat die al — bij een update over een bestaande installatie — dan
gebeurt er niets. Zo kan een update-zip nooit je eigen db met echte incidenten overschrijven,
ook niet als je 'm zonder nadenken over je bestaande installatiemap uitpakt.

## Beveiliging

Commit nooit je eigen `P2000Dashboard/appsettings.json` — dit bestand kan een echt
MQTT-wachtwoord bevatten en is bewust toegevoegd aan `.gitignore`.
