commit a995029111eab769f1e110b7ec2f0dceddb8fd6b
Author: Jens Kristoffersson <jens.se@icloud.com>
AuthorDate: Sat Apr 4 09:51:32 2026 +0200
Commit: Jens Kristoffersson <jens.se@icloud.com>
CommitDate: Sat Apr 4 09:51:32 2026 +0200
Städa upp — ta bort föråldrade filer
Ta bort gamla cage-skript, oanvända systemd-tjänster, interna spec-
och planeringsdokument. Flytta kiosk/README.md till root så GitHub
visar den direkt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
README.md | 255 ++++++++++++++++++++++++++++++++++++++++++-
kiosk-admin-spec.md | 258 --------------------------------------------
kiosk-display.service | 28 -----
kiosk-server.service | 17 ---
kiosk/.gitignore | 17 ---
kiosk/README.md | 254 -------------------------------------------
kiosk/START.md | 28 -----
kiosk/kiosk-display.service | 23 ----
kiosk/plans.md | 0
start.sh | 78 --------------
sudoers-kiosk | 1 -
11 files changed, 254 insertions(+), 705 deletions(-)
diff --git a/README.md b/README.md
index f198c27..67c4cf7 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,254 @@
-# infodisplay
+# Kiosk
+
+Digitalt skyltfönster / displayhanterare för Linux (Debian 13). Visar webbsidor, YouTube, bilder, video och lokala HTML-filer i helskärm via Chromium under Sway (Wayland). Styrs via en webbaserad adminpanel.
+
+---
+
+## Installation
+
+```bash
+sudo bash install.sh
+sudo reboot
+```
+
+Kiosken startar automatiskt vid omstart via autoinloggning på tty1.
+
+### Krav
+
+| Paket | Syfte |
+|---|---|
+| `sway` | Wayland-compositor |
+| `chromium` | Kiosk-webbläsare |
+| `python3-flask`, `python3-flask-socketio` | Webbserver |
+| `python3-apscheduler` | Schemaläggare |
+| `python3-psutil`, `python3-eventlet` | Systeminfo, async |
+| `iw`, `wpasupplicant` | Wi-Fi-hantering |
+| `curl` | Nätverkstest vid uppstart |
+
+---
+
+## Adminpanel
+
+```
+http://<maskinens-IP>:5000/admin
+```
+
+Standardinloggning — ändra i `kiosk/start.sh`:
+
+| Variabel | Standardvärde |
+|---|---|
+| `KIOSK_USER` | `mrfox` |
+| `KIOSK_PASS` | `qweasdzxc` |
+| `SECRET_KEY` | `kiosk-hemlig-nyckel-byt-garna` |
+
+---
+
+## Funktioner
+
+### Visa nu
+Visa något direkt utan att det läggs till i schemat:
+- **URL** — valfri webbadress, YouTube-länk konverteras automatiskt till embed
+- **Ladda upp fil** — video, bild, HTML, PDF/presentation
+- **Lokal fil** — bläddra bland filer på servern
+- **Töm skärm** — visar idle-skärm med IP-adress
+
+### Schema
+Jobb roterar automatiskt i ordning. Varje jobb har en varaktighet i minuter (decimaler OK, ex. `0.5` = 30 sek).
+
+| Typ | Beskrivning |
+|---|---|
+| `url` | Valfri webbadress |
+| `youtube` | YouTube-liveflöde eller video |
+| `video` | Videofil (mp4, webm, avi, mkv, mov) |
+| `image` | Bildfil (jpg, png, gif, webp, bmp) |
+| `pdf` | PDF eller presentation (ppt, pptx, odp) |
+| `kiosk_chat` | Inbyggd livechat i helskärm |
+
+Videolängd detekteras automatiskt vid filval.
+
+### Löptext (ticker)
+Rullande textrad som overlay. Aktiveras/stängs av utan omstart.
+
+- **Källa** — manuell text eller RSS-flöde (uppdateras automatiskt)
+- **Scrollläge** — en rad i taget eller löpande (kontinuerligt)
+- **Position** — nederkant eller överkant
+- **Hastighet**, **textfärg**, **storlek**, **typsnitt**, **bakgrundsfärg**, **opacitet**
+- **Separator** mellan rader i löpande läge
+
+**BBCode:**
+
+| Tagg | Effekt |
+|---|---|
+| `[b]...[/b]` | Fet |
+| `[i]...[/i]` | Kursiv |
+| `[u]...[/u]` | Understruken |
+| `[s]...[/s]` | Genomstruken |
+| `[color=#ff0000]...[/color]` | Textfärg |
+| `[size=64]...[/size]` | Storlek i px |
+| `[shadow]...[/shadow]` | Skugga |
+| `[glow=#00ff00]...[/glow]` | Glödeffekt |
+
+### Livechat
+- **Kiosk Livechat** — inbyggd chat, besökare ansluter via QR-kod på mobilen. Kan visas som helskärm (schema-typ `kiosk_chat`) eller som overlay ovanpå annat innehåll.
+- **YouTube Livechat** — overlay som visas automatiskt vid YouTube-liveflöde.
+
+Inställningar per chat: position (höger/vänster), bredd, höjd, bakgrundsfärg, opacitet.
+
+### Klocka
+Klock-overlay ovanpå allt innehåll.
+
+- **Stil** — digital (HH:MM:SS) eller analog (canvas med sekundvisare)
+- **Datum** — valfritt datum under klockan (sv: Mån 7 apr)
+- **Position** — övre vänster/höger, nedre vänster/höger, centrerad
+- **Storlek**, **färg**, **opacitet**
+- **Schema** — visa alltid, eller bara under schemalagda aktiviteter
+- Positioneras automatiskt bort från ticker-listen
+
+### Sovläge
+Täcker displayen med svart skärm under angiven tid (ex. 22:00–07:00).
+
+### Wi-Fi
+Hantera trådlöst nätverk direkt från adminpanelen.
+
+- **Status** — aktuell SSID, IP-adress, signalstyrka
+- **Skanna** — listar tillgängliga nätverk med signal och säkerhetstyp
+- **Anslut** — lösenordsmodal (öppna nätverk kräver inget lösenord)
+- **Sparade nätverk** — lista och ta bort
+
+> **Krav:** `wpa_cli` utan lösenord via sudoers. Sätts upp automatiskt av `install.sh`.
+
+### Inställningar
+- **Volym** — systemvolym via PipeWire (`wpctl`)
+- **Ljudprofil** — välj PipeWire-kortprofil (t.ex. HDMI Stereo, Analog Stereo)
+- **Intern display (eDP-1)** — aktivera/inaktivera den inbyggda skärmen med adminpanel
+- **HDMI-utgång** — välj vilken utgång som används (`HDMI-A-1` etc.)
+- **Upplösning** — välj bland tillgängliga lägen eller skriv in manuellt
+
+Om intern display är inaktiverad men **ingen Wi-Fi-anslutning** finns vid uppstart — aktiveras den automatiskt så att adminpanelen alltid är tillgänglig.
+
+### System
+Starta om programmet, starta om datorn, stäng av datorn.
+
+---
+
+## Uppstartflöde
+
+```
+Dator startar
+ └─ Getty autologin → tty1 → .bash_profile
+ └─ kiosk-launcher.sh
+ ├─ Väntar på HDMI-A-1
+ ├─ Startar kiosk/start.sh (Flask) i bakgrunden
+ ├─ Väntar på Flask (127.0.0.1:5000)
+ ├─ Väntar på Wi-Fi / IP-adress (max 40 s)
+ ├─ Genererar /tmp/kiosk-sway-outputs.conf
+ └─ Startar sway
+ └─ sway-apps.sh
+ ├─ Väntar på Wi-Fi / IP (max 40 s)
+ ├─ Pre-seedar Chromium-prefs (translate av)
+ ├─ Workspace 1 (HDMI): kiosk-display → http://<IP>:5000/display
+ └─ Workspace 2 (eDP-1): kiosk-admin → http://<IP>:5000/admin
+```
+
+---
+
+## Filstruktur
+
+```
+display/
+├── install.sh # Installationsscript
+├── start.sh # Gammal cage-baserad start (ej använd)
+└── kiosk/
+ ├── start.sh # Startar Flask (sätter env-vars, exec python3 app.py)
+ ├── kiosk-launcher.sh # Startar Flask + sway, genererar output-config
+ ├── sway.conf # Sway-konfiguration (hide_cursor, fullscreen etc.)
+ ├── sway-apps.sh # Startar Chromium på rätt workspace
+ ├── hdmi-monitor.sh # Övervakar HDMI-anslutning
+ ├── hdmi-wait.sh # Väntar på HDMI vid start
+ ├── kiosk.conf # Genereras av admin (ljud/skärm-inställningar)
+ ├── kiosk.db # SQLite-databas
+ ├── app.py # Flask-app, API-endpoints, WebSocket
+ ├── db.py # Databashjälpfunktioner
+ ├── scheduler.py # Schemarotation (APScheduler)
+ ├── uploads/ # Uppladdade mediefiler
+ ├── static/
+ │ ├── admin.js
+ │ ├── display.js
+ │ ├── style.css
+ │ └── socket.io.min.js # Laddas ner av install.sh
+ └── templates/
+ ├── admin.html
+ ├── display.html
+ ├── login.html
+ ├── chat_display.html
+ └── chat_mobile.html
+```
+
+---
+
+## Konfiguration
+
+### kiosk.conf
+Genereras automatiskt av adminpanelen. Kan redigeras manuellt:
+
+```bash
+KIOSK_DISPLAY_MODE=1920x1080@60Hz
+KIOSK_DISPLAY_OUTPUT=HDMI-A-1
+KIOSK_INTERNAL_DISPLAY=off
+KIOSK_AUDIO_PROFILE_INDEX=1
+```
+
+### Miljövariabler (kiosk/start.sh)
+```bash
+export KIOSK_USER=admin
+export KIOSK_PASS=mittlösenord
+export SECRET_KEY=en-lång-hemlig-sträng
+```
+
+---
+
+## Teknikstack
+
+| Komponent | Teknologi |
+|---|---|
+| Backend | Python 3, Flask, Flask-SocketIO, eventlet |
+| Schemaläggare | APScheduler |
+| Databas | SQLite |
+| Frontend | Vanilla JS, Socket.IO |
+| Compositor | Sway (Wayland) |
+| Webbläsare | Chromium (kiosk-läge, ozone-wayland) |
+| Ljud | PipeWire (`wpctl`, `pw-cli`) |
+| Wi-Fi | wpa_supplicant + wpa_cli |
+
+---
+
+## Felsökning
+
+**Kiosken startar inte:**
+```bash
+bash /home/mrfox/codes/display/kiosk/kiosk-launcher.sh
+```
+
+**Flask svarar inte:**
+```bash
+cd /home/mrfox/codes/display/kiosk && bash start.sh
+```
+
+**Sway startar inte / svart skärm:**
+```bash
+# Kontrollera att HDMI är anslutet, sedan:
+SWAYSOCK=$(ls /run/user/$(id -u)/sway-ipc.*.sock 2>/dev/null | head -1)
+swaymsg -s "$SWAYSOCK" exit
+```
+
+**Wi-Fi-sektionen i admin visar "sudo saknas":**
+```bash
+echo 'mrfox ALL=(ALL) NOPASSWD: /usr/sbin/wpa_cli' | sudo tee /etc/sudoers.d/kiosk-wifi
+sudo chmod 440 /etc/sudoers.d/kiosk-wifi
+```
+
+**Markör syns på displayen:**
+Kontrollera att `seat seat0 hide_cursor 3000` finns i `sway.conf` (läggs dit av install.sh).
+
+**Translate-popup i Chromium:**
+`sway-apps.sh` pre-seedar `Default/Preferences` med `"translate": {"enabled": false}` innan Chromium startar. Om det ändå visas: ta bort `/tmp/kiosk-display` och starta om.
diff --git a/kiosk-admin-spec.md b/kiosk-admin-spec.md
deleted file mode 100644
index d02b791..0000000
--- a/kiosk-admin-spec.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# Kiosk Admin Panel — Specifikation & Nuläge
-
-## Systembeskrivning
-
-Lokalt hostad kiosk på x86 Debian 13-maskin.
-Chromium kör fullskärm via Cage (Wayland) och visar en lokal Flask-app.
-Admin-panel nås från valfri enhet på lokalt nätverk.
-Innehållsbyte sker via WebSocket — ingen omladdning, inget flicker.
-
----
-
-## Maskin & miljö
-
-| Egenskap | Värde |
-|----------|-------|
-| OS | Debian 13 (trixie), x86 |
-| Användare | `mrfox` (uid=1000) |
-| Projektkatalog | `/home/mrfox/codes/display/` |
-| Compositor | Cage (Wayland), `-m last` (väljer sist ansluten skärm) |
-| Skärmar | `eDP-1` (inbyggd), `HDMI-A-1` (extern, används) |
-| IP (LAN) | `192.168.0.83` |
-| Port | `5000` |
-
----
-
-## Projektstruktur
-
-```
-display/
-├── start.sh ← Huvudskript. Startar Flask + Cage i loop.
-├── install.sh ← Installerar paket + systemd-tjänster
-├── kiosk-server.service ← systemd: Flask-server
-├── kiosk-display.service ← systemd: Cage + Chromium
-├── sudoers-kiosk ← Sudoers-regel för reboot utan lösenord
-└── kiosk/
- ├── app.py ← Flask-app, routes, SocketIO, auth, system-API
- ├── db.py ← SQLite CRUD (jobs + state)
- ├── scheduler.py ← APScheduler, reload_jobs()
- ├── kiosk.db ← SQLite-databas (auto-skapas)
- ├── templates/
- │ ├── display.html ← Fullskärmssida (laddas en gång av Chromium)
- │ ├── admin.html ← Admin-panel (svenska)
- │ └── login.html ← Inloggningsformulär
- └── static/
- ├── display.js ← WebSocket-klient för display
- ├── admin.js ← Admin-logik (fetch + SocketIO)
- └── style.css ← Delade stilar (mörkt tema)
-```
-
----
-
-## Starta systemet
-
-```bash
-bash /home/mrfox/codes/display/start.sh
-```
-
-`start.sh` kör i en loop: om Cage eller Flask kraschar startar den om automatiskt.
-PIDs sparas till `/tmp/kiosk.pids` (format: `FLASK_PID CAGE_PID`) — används av `/api/restart`.
-
-### Autologin + autostart vid boot
-
-```bash
-# Getty autologin på tty1
-sudo mkdir -p /etc/systemd/system/getty@tty1.service.d/
-sudo tee /etc/systemd/system/getty@tty1.service.d/autologin.conf << 'EOF'
-[Service]
-ExecStart=
-ExecStart=-/sbin/agetty --autologin mrfox --noclear %I $TERM
-EOF
-
-# Autostart via .bash_profile
-echo '[[ -z $DISPLAY && $(tty) == /dev/tty1 ]] && exec bash /home/mrfox/codes/display/start.sh' >> ~/.bash_profile
-```
-
----
-
-## Miljövariabler (start.sh + kiosk-server.service)
-
-| Variabel | Värde |
-|----------|-------|
-| `KIOSK_USER` | `mrfox` |
-| `KIOSK_PASS` | `qweasdzxc` |
-| `SECRET_KEY` | `kiosk-hemlig-nyckel-byt-garna` |
-
-**VIKTIGT:** `SECRET_KEY` måste vara fast och identisk i alla instanser. Annars ogiltigförklaras sessioner vid omstart.
-
----
-
-## Autentisering
-
-Ersatte HTTP Basic Auth med sessionsbaserat inloggningsformulär (fungerar i alla webbläsare utan HTTPS).
-
-- `GET /login` — visar formulär
-- `POST /login` — validerar mot `KIOSK_USER`/`KIOSK_PASS`, sätter `session['logged_in']`
-- `GET /logout` — rensar session
-- `login_required`-decorator skyddar `/admin` och alla `/api/*`-routes
-- `/display` kräver ingen auth
-
----
-
-## Flask Routes
-
-| Method | Route | Auth | Beskrivning |
-|--------|-------|------|-------------|
-| GET | `/display` | Nej | Fullskärmssida för Chromium |
-| GET/POST | `/login` | Nej | Inloggning |
-| GET | `/logout` | Nej | Logga ut |
-| GET | `/admin` | Ja | Admin-panel |
-| GET | `/api/sysinfo` | Ja | CPU, RAM, disk, uptime, aktiv källa |
-| GET | `/api/jobs` | Ja | Lista alla schemalagda jobb |
-| POST | `/api/jobs` | Ja | Lägg till jobb |
-| DELETE | `/api/jobs/<id>` | Ja | Ta bort jobb |
-| PATCH | `/api/jobs/<id>` | Ja | Toggla aktivt/inaktivt |
-| POST | `/api/restart` | Ja | Starta om kiosk-programmet |
-| POST | `/api/reboot` | Ja | Starta om hela datorn (`sudo reboot`) |
-
----
-
-## WebSocket
-
-### Server → Display
-
-```python
-socketio.emit('switch', { 'type': 'url'|'video'|'local', 'source': '...' })
-```
-
-### Admin → Server
-
-```python
-# Event: admin_switch
-# data = { type, source }
-# Sparar till DB + forwardar till display
-```
-
-### Reconnect-hantering
-
-Vid WebSocket-reconnect (t.ex. efter Chromium-reload) re-emittar servern senaste state från DB automatiskt via `on_connect`.
-
----
-
-## Display-lager
-
-Tre lager i `display.html`, bara ett synligt åt gången:
-
-| Lager | ID | Användes för |
-|-------|----|--------------|
-| iframe | `layer-iframe` | URL-visning |
-| video | `layer-video` | Videofiler |
-| local | `layer-local` | Lokal HTML-injektion |
-
-Muspekaren är dold via `cursor: none !important` på alla element.
-
----
-
-## Chromium-flaggor (start.sh)
-
-```bash
-cage -m last -- chromium \
- --kiosk \
- --no-sandbox \
- --disable-gpu \
- --disable-web-security \
- --user-data-dir=/tmp/chromium-kiosk \
- --disable-infobars \
- --disable-session-crashed-bubble \
- --disable-translate \
- --no-first-run \
- --ozone-platform=wayland \
- http://localhost:5000/display
-```
-
-- `--disable-web-security` krävs för att visa sidor som blockerar iframe-inbäddning (X-Frame-Options), t.ex. Västtrafik avgångstavla
-- `--disable-gpu` + `--no-sandbox` krävs för att Chromium ska starta i kiosk-miljön
-- `-m last` i cage väljer sist ansluten skärm (HDMI när inkopplad)
-
----
-
-## Admin-panel — sektioner
-
-1. **Visa nu** — URL-input, video-input, Töm skärm, Ladda om display
-2. **Schema** — tabell med jobb, formulär för att lägga till
-3. **System** — "Starta om programmet" (dödar cage, start.sh loopar), "Starta om datorn"
-4. **Systeminfo** — CPU/RAM/Disk/Uptime/Aktiv källa, auto-refresh var 10s
-
-### Felhantering i admin.js
-
-Alla `fetch()`-anrop går via `apiFetch()` som:
-- Detekterar redirect till `/login` (ogiltig session) → omdirigerar automatiskt
-- Kastar fel vid `!res.ok`
-
----
-
-## SQLite-schema
-
-```sql
-CREATE TABLE jobs (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- label TEXT NOT NULL,
- time TEXT NOT NULL, -- "HH:MM" 24h
- type TEXT NOT NULL, -- "url", "video", "local"
- source TEXT NOT NULL,
- enabled INTEGER DEFAULT 1
-);
-
-CREATE TABLE state (
- key TEXT PRIMARY KEY,
- value TEXT
- -- Keys: current_type, current_source
-);
-```
-
----
-
-## Installerade Python-paket (via apt)
-
-```
-python3-flask
-python3-flask-socketio
-python3-flask-httpauth (installerat men ej längre använt — kan tas bort)
-python3-apscheduler
-python3-psutil
-python3-eventlet
-```
-
-`pip` saknas på systemet — använd `apt-get install python3-<paket>`.
-
----
-
-## Sudoers — reboot utan lösenord
-
-```bash
-sudo cp /home/mrfox/codes/display/sudoers-kiosk /etc/sudoers.d/kiosk
-sudo chmod 440 /etc/sudoers.d/kiosk
-# Innehåll: mrfox ALL=(ALL) NOPASSWD: /sbin/reboot, /usr/sbin/reboot
-```
-
----
-
-## Kända problem / TODO
-
-- `flask-httpauth` är installerat men används inte längre (ersatt av sessionsauth) — kan rensas bort
-- `import signal` finns i app.py men används inte
-- Iframe fungerar inte för sidor med `X-Frame-Options` utan `--disable-web-security` i Chromium
-- Systemd-tjänsterna (`kiosk-server`, `kiosk-display`) är installerade men **ska vara inaktiverade** — `start.sh` via `.bash_profile` används istället för att undvika dubbla Flask-instanser
- ```bash
- sudo systemctl disable kiosk-server kiosk-display
- sudo systemctl stop kiosk-server kiosk-display
- ```
-- `/api/restart` dödar cage (PID från `/tmp/kiosk.pids`) — fungerar bara när start.sh kör (inte via systemd)
-
----
-
-## socket.io
-
-Serveras lokalt av Flask-SocketIO på `/socket.io/socket.io.js`.
-Används i både `display.html` och `admin.html`.
-**Inte** CDN — fungerar offline.
diff --git a/kiosk-display.service b/kiosk-display.service
deleted file mode 100644
index 07175b8..0000000
--- a/kiosk-display.service
+++ /dev/null
@@ -1,28 +0,0 @@
-[Unit]
-Description=Kiosk Display (Cage + Chromium)
-After=kiosk-server.service
-Requires=kiosk-server.service
-
-[Service]
-User=mrfox
-Group=mrfox
-PAMName=login
-Environment=XDG_RUNTIME_DIR=/run/user/1000
-TTYPath=/dev/tty1
-StandardInput=tty
-ExecStartPre=/bin/bash -c "until curl -sf -o /dev/null http://127.0.0.1:5000/display; do sleep 1; done"
-ExecStart=/usr/bin/cage -- \
- /usr/bin/chromium \
- --kiosk \
- --noerr \
- --disable-infobars \
- --disable-session-crashed-bubble \
- --disable-features=Translate \
- --no-first-run \
- --ozone-platform=wayland \
- http://localhost:5000/display
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
diff --git a/kiosk-server.service b/kiosk-server.service
deleted file mode 100644
index 3530a8a..0000000
--- a/kiosk-server.service
+++ /dev/null
@@ -1,17 +0,0 @@
-[Unit]
-Description=Kiosk Flask Server
-After=network.target
-
-[Service]
-User=mrfox
-WorkingDirectory=/home/mrfox/codes/display/kiosk
-ExecStart=/usr/bin/python3 app.py
-Restart=on-failure
-RestartSec=3
-Environment=KIOSK_USER=mrfox
-Environment=KIOSK_PASS=qweasdzxc
-Environment=SECRET_KEY=kiosk-hemlig-nyckel-byt-garna
-Environment=XDG_RUNTIME_DIR=/run/user/1000
-
-[Install]
-WantedBy=multi-user.target
diff --git a/kiosk/.gitignore b/kiosk/.gitignore
deleted file mode 100644
index 84afa8c..0000000
--- a/kiosk/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-__pycache__/
-*.py[cod]
-.venv/
-venv/
-env/
-*.sqlite3
-kiosk.db
-kiosk.conf
-uploads/
-node_modules/
-.DS_Store
-.env
-*.log
-*.pid
-.vscode/
-/.cache/
-*.pyc
\ No newline at end of file
diff --git a/kiosk/README.md b/kiosk/README.md
deleted file mode 100644
index 67c4cf7..0000000
--- a/kiosk/README.md
+++ /dev/null
@@ -1,254 +0,0 @@
-# Kiosk
-
-Digitalt skyltfönster / displayhanterare för Linux (Debian 13). Visar webbsidor, YouTube, bilder, video och lokala HTML-filer i helskärm via Chromium under Sway (Wayland). Styrs via en webbaserad adminpanel.
-
----
-
-## Installation
-
-```bash
-sudo bash install.sh
-sudo reboot
-```
-
-Kiosken startar automatiskt vid omstart via autoinloggning på tty1.
-
-### Krav
-
-| Paket | Syfte |
-|---|---|
-| `sway` | Wayland-compositor |
-| `chromium` | Kiosk-webbläsare |
-| `python3-flask`, `python3-flask-socketio` | Webbserver |
-| `python3-apscheduler` | Schemaläggare |
-| `python3-psutil`, `python3-eventlet` | Systeminfo, async |
-| `iw`, `wpasupplicant` | Wi-Fi-hantering |
-| `curl` | Nätverkstest vid uppstart |
-
----
-
-## Adminpanel
-
-```
-http://<maskinens-IP>:5000/admin
-```
-
-Standardinloggning — ändra i `kiosk/start.sh`:
-
-| Variabel | Standardvärde |
-|---|---|
-| `KIOSK_USER` | `mrfox` |
-| `KIOSK_PASS` | `qweasdzxc` |
-| `SECRET_KEY` | `kiosk-hemlig-nyckel-byt-garna` |
-
----
-
-## Funktioner
-
-### Visa nu
-Visa något direkt utan att det läggs till i schemat:
-- **URL** — valfri webbadress, YouTube-länk konverteras automatiskt till embed
-- **Ladda upp fil** — video, bild, HTML, PDF/presentation
-- **Lokal fil** — bläddra bland filer på servern
-- **Töm skärm** — visar idle-skärm med IP-adress
-
-### Schema
-Jobb roterar automatiskt i ordning. Varje jobb har en varaktighet i minuter (decimaler OK, ex. `0.5` = 30 sek).
-
-| Typ | Beskrivning |
-|---|---|
-| `url` | Valfri webbadress |
-| `youtube` | YouTube-liveflöde eller video |
-| `video` | Videofil (mp4, webm, avi, mkv, mov) |
-| `image` | Bildfil (jpg, png, gif, webp, bmp) |
-| `pdf` | PDF eller presentation (ppt, pptx, odp) |
-| `kiosk_chat` | Inbyggd livechat i helskärm |
-
-Videolängd detekteras automatiskt vid filval.
-
-### Löptext (ticker)
-Rullande textrad som overlay. Aktiveras/stängs av utan omstart.
-
-- **Källa** — manuell text eller RSS-flöde (uppdateras automatiskt)
-- **Scrollläge** — en rad i taget eller löpande (kontinuerligt)
-- **Position** — nederkant eller överkant
-- **Hastighet**, **textfärg**, **storlek**, **typsnitt**, **bakgrundsfärg**, **opacitet**
-- **Separator** mellan rader i löpande läge
-
-**BBCode:**
-
-| Tagg | Effekt |
-|---|---|
-| `[b]...[/b]` | Fet |
-| `[i]...[/i]` | Kursiv |
-| `[u]...[/u]` | Understruken |
-| `[s]...[/s]` | Genomstruken |
-| `[color=#ff0000]...[/color]` | Textfärg |
-| `[size=64]...[/size]` | Storlek i px |
-| `[shadow]...[/shadow]` | Skugga |
-| `[glow=#00ff00]...[/glow]` | Glödeffekt |
-
-### Livechat
-- **Kiosk Livechat** — inbyggd chat, besökare ansluter via QR-kod på mobilen. Kan visas som helskärm (schema-typ `kiosk_chat`) eller som overlay ovanpå annat innehåll.
-- **YouTube Livechat** — overlay som visas automatiskt vid YouTube-liveflöde.
-
-Inställningar per chat: position (höger/vänster), bredd, höjd, bakgrundsfärg, opacitet.
-
-### Klocka
-Klock-overlay ovanpå allt innehåll.
-
-- **Stil** — digital (HH:MM:SS) eller analog (canvas med sekundvisare)
-- **Datum** — valfritt datum under klockan (sv: Mån 7 apr)
-- **Position** — övre vänster/höger, nedre vänster/höger, centrerad
-- **Storlek**, **färg**, **opacitet**
-- **Schema** — visa alltid, eller bara under schemalagda aktiviteter
-- Positioneras automatiskt bort från ticker-listen
-
-### Sovläge
-Täcker displayen med svart skärm under angiven tid (ex. 22:00–07:00).
-
-### Wi-Fi
-Hantera trådlöst nätverk direkt från adminpanelen.
-
-- **Status** — aktuell SSID, IP-adress, signalstyrka
-- **Skanna** — listar tillgängliga nätverk med signal och säkerhetstyp
-- **Anslut** — lösenordsmodal (öppna nätverk kräver inget lösenord)
-- **Sparade nätverk** — lista och ta bort
-
-> **Krav:** `wpa_cli` utan lösenord via sudoers. Sätts upp automatiskt av `install.sh`.
-
-### Inställningar
-- **Volym** — systemvolym via PipeWire (`wpctl`)
-- **Ljudprofil** — välj PipeWire-kortprofil (t.ex. HDMI Stereo, Analog Stereo)
-- **Intern display (eDP-1)** — aktivera/inaktivera den inbyggda skärmen med adminpanel
-- **HDMI-utgång** — välj vilken utgång som används (`HDMI-A-1` etc.)
-- **Upplösning** — välj bland tillgängliga lägen eller skriv in manuellt
-
-Om intern display är inaktiverad men **ingen Wi-Fi-anslutning** finns vid uppstart — aktiveras den automatiskt så att adminpanelen alltid är tillgänglig.
-
-### System
-Starta om programmet, starta om datorn, stäng av datorn.
-
----
-
-## Uppstartflöde
-
-```
-Dator startar
- └─ Getty autologin → tty1 → .bash_profile
- └─ kiosk-launcher.sh
- ├─ Väntar på HDMI-A-1
- ├─ Startar kiosk/start.sh (Flask) i bakgrunden
- ├─ Väntar på Flask (127.0.0.1:5000)
- ├─ Väntar på Wi-Fi / IP-adress (max 40 s)
- ├─ Genererar /tmp/kiosk-sway-outputs.conf
- └─ Startar sway
- └─ sway-apps.sh
- ├─ Väntar på Wi-Fi / IP (max 40 s)
- ├─ Pre-seedar Chromium-prefs (translate av)
- ├─ Workspace 1 (HDMI): kiosk-display → http://<IP>:5000/display
- └─ Workspace 2 (eDP-1): kiosk-admin → http://<IP>:5000/admin
-```
-
----
-
-## Filstruktur
-
-```
-display/
-├── install.sh # Installationsscript
-├── start.sh # Gammal cage-baserad start (ej använd)
-└── kiosk/
- ├── start.sh # Startar Flask (sätter env-vars, exec python3 app.py)
- ├── kiosk-launcher.sh # Startar Flask + sway, genererar output-config
- ├── sway.conf # Sway-konfiguration (hide_cursor, fullscreen etc.)
- ├── sway-apps.sh # Startar Chromium på rätt workspace
- ├── hdmi-monitor.sh # Övervakar HDMI-anslutning
- ├── hdmi-wait.sh # Väntar på HDMI vid start
- ├── kiosk.conf # Genereras av admin (ljud/skärm-inställningar)
- ├── kiosk.db # SQLite-databas
- ├── app.py # Flask-app, API-endpoints, WebSocket
- ├── db.py # Databashjälpfunktioner
- ├── scheduler.py # Schemarotation (APScheduler)
- ├── uploads/ # Uppladdade mediefiler
- ├── static/
- │ ├── admin.js
- │ ├── display.js
- │ ├── style.css
- │ └── socket.io.min.js # Laddas ner av install.sh
- └── templates/
- ├── admin.html
- ├── display.html
- ├── login.html
- ├── chat_display.html
- └── chat_mobile.html
-```
-
----
-
-## Konfiguration
-
-### kiosk.conf
-Genereras automatiskt av adminpanelen. Kan redigeras manuellt:
-
-```bash
-KIOSK_DISPLAY_MODE=1920x1080@60Hz
-KIOSK_DISPLAY_OUTPUT=HDMI-A-1
-KIOSK_INTERNAL_DISPLAY=off
-KIOSK_AUDIO_PROFILE_INDEX=1
-```
-
-### Miljövariabler (kiosk/start.sh)
-```bash
-export KIOSK_USER=admin
-export KIOSK_PASS=mittlösenord
-export SECRET_KEY=en-lång-hemlig-sträng
-```
-
----
-
-## Teknikstack
-
-| Komponent | Teknologi |
-|---|---|
-| Backend | Python 3, Flask, Flask-SocketIO, eventlet |
-| Schemaläggare | APScheduler |
-| Databas | SQLite |
-| Frontend | Vanilla JS, Socket.IO |
-| Compositor | Sway (Wayland) |
-| Webbläsare | Chromium (kiosk-läge, ozone-wayland) |
-| Ljud | PipeWire (`wpctl`, `pw-cli`) |
-| Wi-Fi | wpa_supplicant + wpa_cli |
-
----
-
-## Felsökning
-
-**Kiosken startar inte:**
-```bash
-bash /home/mrfox/codes/display/kiosk/kiosk-launcher.sh
-```
-
-**Flask svarar inte:**
-```bash
-cd /home/mrfox/codes/display/kiosk && bash start.sh
-```
-
-**Sway startar inte / svart skärm:**
-```bash
-# Kontrollera att HDMI är anslutet, sedan:
-SWAYSOCK=$(ls /run/user/$(id -u)/sway-ipc.*.sock 2>/dev/null | head -1)
-swaymsg -s "$SWAYSOCK" exit
-```
-
-**Wi-Fi-sektionen i admin visar "sudo saknas":**
-```bash
-echo 'mrfox ALL=(ALL) NOPASSWD: /usr/sbin/wpa_cli' | sudo tee /etc/sudoers.d/kiosk-wifi
-sudo chmod 440 /etc/sudoers.d/kiosk-wifi
-```
-
-**Markör syns på displayen:**
-Kontrollera att `seat seat0 hide_cursor 3000` finns i `sway.conf` (läggs dit av install.sh).
-
-**Translate-popup i Chromium:**
-`sway-apps.sh` pre-seedar `Default/Preferences` med `"translate": {"enabled": false}` innan Chromium startar. Om det ändå visas: ta bort `/tmp/kiosk-display` och starta om.
diff --git a/kiosk/START.md b/kiosk/START.md
deleted file mode 100644
index b94c8b9..0000000
--- a/kiosk/START.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Startup script
-----------------
-
-This repository includes `start.sh` which will, if present, read `kiosk.conf` from the project root and attempt to apply the `KIOSK_DISPLAY_MODE` (e.g. `1920x1080`) using available system tools (`xrandr`, `swaymsg`, `wlr-randr`) before launching the app.
-
-Quick usage:
-
-1. Make the script executable:
-
-```bash
-chmod +x start.sh
-```
-
-2. Set `KIOSK_DISPLAY_MODE` in `kiosk.conf` (example):
-
-```
-KIOSK_DISPLAY_MODE=1920x1080
-```
-
-3. Start the kiosk:
-
-```bash
-./start.sh
-```
-
-Notes:
-- The display mode application is best-effort and depends on tools and compositor support on the target machine.
-- If immediate mode application fails, consider applying the mode in the system startup or using compositor-specific configuration.
diff --git a/kiosk/kiosk-display.service b/kiosk/kiosk-display.service
deleted file mode 100644
index 1b8a47c..0000000
--- a/kiosk/kiosk-display.service
+++ /dev/null
@@ -1,23 +0,0 @@
-[Unit]
-Description=Kiosk Display (Sway + Chromium)
-After=kiosk-server.service
-Requires=kiosk-server.service
-StartLimitIntervalSec=0
-
-[Service]
-User=mrfox
-Group=mrfox
-PAMName=login
-Environment=XDG_RUNTIME_DIR=/run/user/1000
-Environment=HOME=/home/mrfox
-TTYPath=/dev/tty1
-StandardInput=tty
-StandardOutput=tty
-StandardError=journal
-TimeoutStartSec=infinity
-ExecStart=/home/mrfox/codes/display/kiosk/kiosk-launcher.sh
-Restart=always
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
diff --git a/kiosk/plans.md b/kiosk/plans.md
deleted file mode 100644
index e69de29..0000000
diff --git a/start.sh b/start.sh
deleted file mode 100755
index 17cbfb1..0000000
--- a/start.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-KIOSK_DIR="$SCRIPT_DIR/kiosk"
-PID_FILE="/tmp/kiosk.pids"
-
-export KIOSK_USER="${KIOSK_USER:-mrfox}"
-export KIOSK_PASS="${KIOSK_PASS:-qweasdzxc}"
-export SECRET_KEY="${SECRET_KEY:-kiosk-hemlig-nyckel-byt-garna}"
-
-cleanup() {
- echo "Stänger ner..."
- kill "$FLASK_PID" 2>/dev/null
- kill "$CAGE_PID" 2>/dev/null
- rm -f "$PID_FILE"
- wait 2>/dev/null
- exit 0
-}
-trap cleanup SIGINT SIGTERM
-
-while true; do
- # Läs konfiguration
- KIOSK_AUDIO_PROFILE_INDEX=1
- KIOSK_DISPLAY_OUTPUT="last"
- [ -f "$SCRIPT_DIR/kiosk.conf" ] && source "$SCRIPT_DIR/kiosk.conf"
- [[ "$KIOSK_DISPLAY_OUTPUT" != "first" && "$KIOSK_DISPLAY_OUTPUT" != "last" ]] && KIOSK_DISPLAY_OUTPUT="last"
- if [ "$KIOSK_AUDIO_PROFILE_INDEX" != "1" ]; then
- AUDIO_DEV=$(pw-dump 2>/dev/null | python3 -c "
-import json,sys
-for n in json.load(sys.stdin):
- if n.get('type')=='PipeWire:Interface:Device':
- p=n.get('info',{}).get('props',{})
- if p.get('media.class')=='Audio/Device':
- print(n['id']); break
-" 2>/dev/null)
- [ -n "$AUDIO_DEV" ] && pw-cli s "$AUDIO_DEV" Profile "{ index: $KIOSK_AUDIO_PROFILE_INDEX }" 2>/dev/null && sleep 0.3
- fi
-
- echo "Startar Flask..."
- cd "$KIOSK_DIR"
- python3 app.py &
- FLASK_PID=$!
-
- echo "Väntar på Flask..."
- until curl -sf -o /dev/null http://127.0.0.1:5000/display; do
- sleep 1
- kill -0 "$FLASK_PID" 2>/dev/null || break
- done
-
- kill -0 "$FLASK_PID" 2>/dev/null || { echo "Flask kraschade, startar om..."; sleep 2; continue; }
-
- echo "Flask kör. Startar Cage + Chromium..."
- cage -m "$KIOSK_DISPLAY_OUTPUT" -- chromium \
- --kiosk \
- --no-sandbox \
- --disable-translate \
- --disable-web-security \
- --enable-features=VaapiVideoDecoder,VaapiVideoEncoder \
- --disable-features=UseChromeOSDirectVideoDecoder \
- --user-data-dir=/tmp/chromium-kiosk \
- --disable-infobars \
- --disable-session-crashed-bubble \
- --disable-features=Translate \
- --no-first-run \
- --autoplay-policy=no-user-gesture-required \
- --ozone-platform=wayland \
- http://localhost:5000/display &
- CAGE_PID=$!
-
- echo "$FLASK_PID $CAGE_PID" > "$PID_FILE"
- echo "Kiosk igång. Ctrl+C för att stänga."
-
- wait "$CAGE_PID"
- echo "Cage avslutades, startar om..."
- kill "$FLASK_PID" 2>/dev/null
- wait "$FLASK_PID" 2>/dev/null
- sleep 2
-done
diff --git a/sudoers-kiosk b/sudoers-kiosk
deleted file mode 100644
index 4519f30..0000000
--- a/sudoers-kiosk
+++ /dev/null
@@ -1 +0,0 @@
-mrfox ALL=(ALL) NOPASSWD: /sbin/reboot, /usr/sbin/reboot