## monitor-im-flur ![Build Status](https://git.rivercry.com/wg/monitor-im-flur/badges/master/pipeline.svg) Hallway / common-area wall monitor dashboard. A single-page React + Vite app that surfaces useful household + transit + weather + fun data on a passive display. ### Key Features * Realtime-ish auto‑refresh via git commit hash file (`/git-hash.html`) – hot-reloads the deployed page when a new build is published. * Dynamic theming (day / evening / night) based on current time. * Public transport departures (KVV) for two nearby stops (IDs 7000044 & 7000045). * Weather (current, hourly, daily min/max) via Open‑Meteo. * Flatastic chores integration (tasks + flatmates) with API key. * Home Assistant readings (tent temperature + humidity) displayed in a faux terminal with rotating shitposts. * 4:20 easter egg card + Amogus sprite + other playful flourishes. * Docker / Nginx static deployment image (`git.rivercry.com/wg/monitor-im-flur:latest`). * Strict linting + formatting (ESLint AirBnB + Prettier + Biome optional). * Zustand + RTK (toolkit present) state management (currently Zustand in active use). ### Tech Stack * React 19 + TypeScript + Vite * Zustand (with devtools) for app stores (weather, kvv, flatastic, home assistant) * Nginx (static file serving) inside minimal Docker image * Open‑Meteo, Flatastic, KVV, Home Assistant external APIs * Git hash pipeline script to trigger client self‑reloads ### Project Structure (abridged) ``` src/ api/ # External data fetchers components/ # UI building blocks (Cards, Timetable, Weather, Terminal, etc.) store/ # Zustand stores encapsulating fetch + state types/ # Type definitions for external data pipeline/ create-git-hash-html.sh # Injects current commit hash into dist Dockerfile # Nginx static hosting docker-compose.yml # Example runtime service definition ``` ### Environment Configuration Create a `.env` (or `.env.local`) for Vite with the following (only what you need): ``` VITE_FLATTASTIC_API_KEY=your_flatastic_api_key # (Planned) VITE_HOME_ASSISTANT_TOKEN=your_long_lived_token # NOTE: currently hardcoded – see Security section ``` Vite automatically exposes variables prefixed with `VITE_` to the client bundle. Do NOT place secrets without that prefix – but remember: anything in the client bundle is public. For sensitive data consider a tiny proxy backend instead of calling APIs directly from the browser. ### Security Notice `src/api/homeAssistant.ts` currently contains a hard‑coded long‑lived Home Assistant token. This should be refactored before any public deployment: 1. Remove the literal token from the repository. 2. Load it via environment variable during build (`import.meta.env.VITE_HOME_ASSISTANT_TOKEN`) OR 3. Prefer a minimal server proxy so the token never ships to the browser. ### Development Install dependencies (Bun is inferred from `bun.lock`, but npm/pnpm/yarn also work). ``` bun install ``` Run the dev server (HTTPS support possible with `vite-plugin-mkcert` if certificates are trusted): ``` bun run dev ``` Open: http://localhost:5173 ### Lint & Format ``` bun run lint ``` Optionally run Biome (if desired): ``` npx biome check --apply . ``` ### Build ``` bun run build ``` Outputs production bundle to `dist/`. ### Docker Image Build locally: ``` docker build -t monitor-im-flur:local . ``` Run: ``` docker run --rm -p 9123:80 monitor-im-flur:local ``` Or use compose (uses published image): ``` docker compose up -d ``` Visit: http://localhost:9123 ### Git Hash Auto‑Reload Mechanism `pipeline/create-git-hash-html.sh` writes the current commit (`$GITHUB_SHA`) to `dist/git-hash.html` during CI. The dashboard polls `/git-hash.html` every 10s; when the value changes it performs `window.location.reload()`. Ensure your CI runs the script after `vite build` and before creating the Docker image. Pseudo CI step example: ``` vite build GITHUB_SHA=$(git rev-parse HEAD) ./pipeline/create-git-hash-html.sh docker build -t git.rivercry.com/wg/monitor-im-flur:$(git rev-parse --short HEAD) . ``` ### Data Sources * KVV Departures: Public endpoint (JSON) for stop IDs 7000044 / 7000045. * Weather: Open‑Meteo forecast API (lat 49.0094, lon 8.4044, Europe/Berlin TZ). * Flatastic: Auth via `x-api-key` (user provided). * Home Assistant: Long‑lived bearer token (refactor recommended). ### Adding a New Card 1. Create a directory under `src/components//` with `NewCard.tsx` & optional `style.module.css`. 2. Wrap content with existing `Card` component (`icon` + `name` props). 3. Register inside `Dashboard.tsx` where layout lives (using `CardColumn` / `CardRow`). ### State Management Notes All data fetching is encapsulated inside zustand store `fetch` methods invoked on an interval within the respective components. Consider centralizing polling or using React Query if complexity grows. ### Potential Improvements / TODO * Remove hard‑coded Home Assistant token. * Error + loading states (currently optimistic, failures would be silent / console only). * Retry & backoff strategy for network calls. * Dark mode override / manual theme toggle. * Accessibility pass (ARIA, focus management) – current dashboard is mostly passive. * Tests (none yet). Could add Vitest + React Testing Library. * Switch transit API code to gracefully handle outages (KVV sometimes rate limits). ### License Add a license file if you plan to share externally (currently unspecified). ### Support / Contact Internal project (wg). For issues open a ticket on Gitea: https://git.rivercry.com/wg/monitor-im-flur --- Generated README draft – adjust repository paths / badge branch name if different (e.g., replace `master` with your default branch).