149 lines
4.2 KiB
Markdown

# Virtueller Gesundheitsassistent
Java desktop application that receives binary health predictions via MQTT, stores them in SQLite, computes rolling risk ratios, and visualizes the result in a dashboard with an avatar streaming view.
## Features
- Swing desktop UI with two tabs:
- `Avatar Streaming` (embedded JCEF browser, default `http://localhost`)
- `Dashboard` (time series chart + problem level bar)
- MQTT client subscriber (`tcp://localhost:1883`) for prediction events
- SQLite persistence (`data/health.db`)
- Rolling ratio evaluation and automatic risk level classification:
- `NONE` for `< 0.5`
- `WARNING` for `>= 0.5`
- `HIGH` for `>= 0.8`
- `DISASTER` for `>= 0.9`
- Writes animation state JSON for Unreal integration
- Optional external process startup:
- Python MQTT simulator
- Unreal/Pixel Streaming scripts
- Custom async logger with file output + rotation
## Tech Stack
- Java 17
- Maven
- Swing + FlatLaf
- JFreeChart
- Eclipse Paho MQTT
- SQLite JDBC
- JCEF (`jcefmaven`)
- JUnit 5 + Mockito (tests)
## Runtime Flow
1. App initializes look and feel and services.
2. MQTT subscriber listens on topic from config (`mqtt.topic`).
3. Incoming JSON payloads are validated in `BinaryEventService`.
4. `prediction` (`0`/`1`) is stored in SQLite.
5. `EvaluationService` computes ratio over last 20 values.
6. `AppState` updates notify UI controllers.
7. Dashboard chart and status bar refresh.
8. Animation state file is written for Unreal consumption.
## Payload Format
Incoming MQTT payload must be JSON like:
```json
{
"valid": true,
"_id": 123,
"prediction": 0
}
```
## Prerequisites
- JDK 17
- Maven 3.9+
- Local MQTT broker on `localhost:1883` (or adjust code/config)
- Windows environment if using bundled process scripts/paths
- Optional: Python (if MQTT simulator should be auto-started)
- Optional: Unreal + Pixel Streaming setup (path-based integration)
## Configuration
Main config: `src/main/resources/config/application.properties`
- `app.mode`: current mode flag (`test`)
- `python.path`: Python executable for simulator startup
- `mqtt.topic`: subscribed topic (default `PREDICTION`)
- `mqtt_sim.enabled`: start simulator process on app startup
- `mqtt_sim.script`: simulator script path
- `unreal.enabled`: start Unreal-related processes
- `unreal.executable`: PowerShell script path for Unreal start
- `unreal.signalling_server.script`: signalling server batch path
Logger config: `src/main/resources/config/logger.properties`
- `logger.level`
- `logger.file.enabled`
- `logger.file`
- `logger.max.size.mb`
## Run
### 1) Start MQTT Broker
Start a broker on `localhost:1883` (for example Mosquitto).
### 2) Start the App
```powershell
mvn clean compile
mvn org.codehaus.mojo:exec-maven-plugin:3.5.0:java -Dexec.mainClass=vassistent.App
```
Or run `vassistent.App` directly from IntelliJ.
### 3) Send Test Data
Option A: enable simulator in `application.properties`:
- set `mqtt_sim.enabled=true`
- verify `python.path` and `mqtt_sim.script`
Option B: publish messages manually to topic `PREDICTION`.
## Tests
Run:
```powershell
mvn test
```
Current state in this repository on Java 17:
- `DataPersistenceServiceTest` and `StatisticsServiceTest` execute.
- Mockito-based tests fail because dependency is `mockito-all:2.0.2-beta` (legacy CGLIB + Java module access issue on modern JDKs).
## Project Structure
```text
src/main/java/vassistent
App.java
bootstrap/ # wiring, context, shutdown sequencing
controller/ # Swing controllers
model/ # state + data types
service/ # MQTT, DB, stats, evaluation, processes
ui/ # App window, dashboard, streaming, widgets
util/ # config + logger
src/main/resources
config/application.properties
config/logger.properties
scripts/mqtt_simulator.py
scripts/start_avatar.ps1
```
## Important Notes
- `AnimationFileService` currently writes to a hardcoded absolute path:
- `C:\Users\Student\Documents\Dannick\Prototyp1\Saved\animation.json`
- Unreal process handling also uses hardcoded PID/script paths.
- On app shutdown, `data/health.db` is deleted by `App.deleteDatabase()`.
- The signalling server process startup in `ProcessManagerService` is prepared but currently not launched (`pb.start()` commented).