Skip to content

Commit 8acce6f

Browse files
committed
feat: update documentation and scripts for improved Raspberry Pi setup and management; remove health monitor script
1 parent 94a2de4 commit 8acce6f

13 files changed

Lines changed: 163 additions & 260 deletions

File tree

README.md

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,82 @@ Real-time floor display system showing schedules, room availability, and announc
55
## Architecture
66

77
```
8-
Browser ──► Next.js Server ──► PostgreSQL
9-
│ WebSocket
10-
┌──────────┼──────────┐
11-
Pi F1 Pi F2 Pi F3
12-
(kiosk) (kiosk) (kiosk)
8+
Admin Browser ──► Next.js Server ──► PostgreSQL
9+
10+
│ Pi nodes connect TO server
11+
│ (no static Pi IPs needed)
12+
13+
┌────── WebSocket ─┼── WebSocket ──┐
14+
▼ ▼ ▼
15+
Pi F1 Pi F2 Pi F3
16+
(kiosk) (kiosk) (kiosk)
1317
```
1418

19+
**Network model**: Pi nodes only need to reach the server IP. Server never initiates connections to Pi. No port forwarding, static Pi IPs, or firewall changes needed on the Pi side.
20+
1521
## Quick Start
1622

17-
### Option 1: Docker (Recommended)
23+
### 1. Deploy Server (Docker)
1824

1925
```bash
20-
# 1. Clone
2126
git clone https://github.com/IN4300-Embedded-Systems-Project/B22_Group06.git
2227
cd B22_Group06
23-
24-
# 2. Configure
25-
cp .env.example .env
26-
27-
# 3. Deploy
28+
cp .env.example .env # edit DB_PASSWORD, NEXTAUTH_SECRET
2829
./scripts/deploy.sh
2930
```
3031

31-
Open http://localhost:3000/admin (login: admin@example.com / admin123)
32+
Admin panel: `http://SERVER_IP:3000/admin` (admin@example.com / admin123)
33+
34+
### 2. Setup Each Raspberry Pi
3235

33-
### Option 2: Development
36+
Each Pi only needs **2 things**: the server IP and its floor number.
3437

3538
```bash
36-
# 1. Install dependencies
37-
pnpm install
39+
# On each Pi — just change the IP and floor number
40+
sudo bash setup.sh --server http://SERVER_IP:3000 --floor 1
41+
sudo reboot
42+
```
3843

39-
# 2. Start PostgreSQL
40-
docker run -d --name db -e POSTGRES_PASSWORD=changeme -e POSTGRES_DB=displaydb -e POSTGRES_USER=displayuser -p 5432:5432 postgres:16-alpine
44+
Or remote one-liner:
45+
```bash
46+
curl -sSL https://raw.githubusercontent.com/IN4300-Embedded-Systems-Project/B22_Group06/main/pi-node/setup.sh | \
47+
sudo bash -s -- --server http://SERVER_IP:3000 --floor 1
48+
sudo reboot
49+
```
4150

42-
# 3. Configure & setup
43-
cp .env.example .env
44-
cd server
45-
pnpm db:push && pnpm db:seed
51+
### 3. Reconfigure a Pi
4652

47-
# 4. Run
48-
pnpm dev
53+
To change server IP or floor, just edit one file and reboot:
54+
```bash
55+
sudo nano /opt/display-node/config.env # change SERVER_URL or FLOOR_ID
56+
sudo reboot
4957
```
5058

51-
## Raspberry Pi Setup
52-
53-
On each Pi (Raspberry Pi OS 64-bit):
59+
## Development
5460

5561
```bash
56-
curl -sSL https://raw.githubusercontent.com/IN4300-Embedded-Systems-Project/B22_Group06/main/pi-node/setup.sh | \
57-
sudo bash -s -- --server-url http://YOUR_SERVER_IP:3000 --floor-id 1
58-
sudo reboot
62+
pnpm install
63+
docker run -d --name db -e POSTGRES_PASSWORD=changeme -e POSTGRES_DB=displaydb -e POSTGRES_USER=displayuser -p 5432:5432 postgres:16-alpine
64+
cp .env.example .env
65+
cd server && pnpm db:push && pnpm db:seed && pnpm dev
5966
```
6067

6168
## Project Structure
6269

6370
```
6471
├── server/ # Next.js app (admin + display + API)
65-
├── deploy/ # Docker Compose
66-
├── pi-node/ # Raspberry Pi setup scripts
67-
└── docs/ # Documentation
72+
├── deploy/ # Docker Compose (server + postgres)
73+
├── pi-node/ # Pi setup: setup.sh, kiosk.sh, update.sh
74+
└── docs/ # Architecture, deployment, networking, API
6875
```
6976

70-
## Features
77+
## How It Works
7178

72-
- **Admin Panel**: `/admin` - Manage schedules, rooms, announcements
73-
- **Floor Display**: `/display/[floorId]` - Full-screen display for Pi
74-
- **Real-time**: WebSocket pushes changes instantly
75-
- **Auto-recovery**: Pi kiosk auto-restarts on crash
79+
1. Server runs Next.js + PostgreSQL in Docker on faculty network
80+
2. Each Pi runs Chromium in kiosk mode pointing to `http://SERVER:3000/display/FLOOR_ID`
81+
3. Pi connects to server via WebSocket — sends heartbeat every 30s
82+
4. Admin changes push instantly to Pi displays via WebSocket
83+
5. Pi auto-restarts kiosk on crash, daily refresh at 4 AM
7684

7785
## Tech Stack
7886

docs/api.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,23 @@ Display routes (`/display/*`) are public.
6565
| Method | Path | Description |
6666
|--------|------|-------------|
6767
| GET | `/api/nodes` | List all Pi node statuses |
68-
| POST | `/api/nodes/heartbeat` | Pi heartbeat (called by health monitor) |
6968

7069
## WebSocket Events
7170

7271
### Server → Client (Display)
7372

7473
| Event | Payload | Description |
7574
|-------|---------|-------------|
76-
| `schedule:update` | `{ floorId, schedules[] }` | Schedule changed |
75+
| `schedule:update` | `{ floorId, schedule }` | Schedule changed |
7776
| `announcement:update` | `{ floorId?, announcement }` | New/updated announcement |
78-
| `room:update` | `{ floorId, rooms[] }` | Room status changed |
7977
| `display:refresh` | `{ floorId? }` | Force full refresh |
8078

8179
### Client → Server
8280

8381
| Event | Payload | Description |
8482
|-------|---------|-------------|
8583
| `join:floor` | `{ floorId }` | Subscribe to floor updates |
86-
| `heartbeat` | `{ floorId, status }` | Pi health report |
84+
| `heartbeat` | `{ floorId, status }` | Pi alive signal (every 30s, updates node status in DB) |
8785

8886
## Query Parameters
8987

docs/deployment.md

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,66 @@
11
# Deployment Guide
22

3-
## Server Deployment (Docker)
3+
## Network Model
4+
5+
```
6+
Faculty Network Server (known IP)
7+
8+
│ Pi nodes connect outbound to server
9+
│ No static Pi IPs needed
10+
┌────┼────┬────┐
11+
Pi1 Pi2 Pi3 Pi4
12+
```
13+
14+
- Server deployed on faculty network — you know its IP
15+
- Pi nodes auto-connect to server — their IPs don't matter
16+
- Heartbeat flows over WebSocket (Pi → Server), no separate monitoring needed
17+
18+
## Server Deployment
419

520
```bash
6-
# 1. Clone & configure
721
git clone https://github.com/IN4300-Embedded-Systems-Project/B22_Group06.git
822
cd B22_Group06
9-
cp .env.example .env
10-
11-
# 2. Deploy
23+
cp .env.example .env # set DB_PASSWORD, NEXTAUTH_SECRET
1224
./scripts/deploy.sh
1325
```
1426

15-
Access admin panel at http://localhost:3000/admin
27+
Verify: `http://SERVER_IP:3000/admin`
1628

1729
## Raspberry Pi Setup
1830

19-
Run on each Pi (Raspberry Pi OS 64-bit):
31+
Each Pi needs only **the server IP** and **its floor number**:
2032

2133
```bash
22-
curl -sSL https://raw.githubusercontent.com/IN4300-Embedded-Systems-Project/B22_Group06/main/pi-node/setup.sh | \
23-
sudo bash -s -- --server-url http://YOUR_SERVER_IP:3000 --floor-id 1
34+
sudo bash setup.sh --server http://SERVER_IP:3000 --floor 1
2435
sudo reboot
2536
```
2637

27-
## Updating
38+
### What this does:
39+
1. Installs Chromium + X11
40+
2. Writes `/opt/display-node/config.env` (2 lines: SERVER_URL, FLOOR_ID)
41+
3. Creates systemd service for kiosk + hourly update check
42+
4. Configures auto-login and fullscreen on boot
2843

29-
### Server
44+
### Reconfigure a Pi
3045
```bash
31-
git pull
32-
./scripts/deploy.sh
46+
sudo nano /opt/display-node/config.env # change SERVER_URL or FLOOR_ID
47+
sudo reboot
3348
```
3449

35-
### Raspberry Pi
50+
### Troubleshooting
51+
52+
| Issue | Fix |
53+
|-------|-----|
54+
| Black screen | `sudo systemctl restart display-kiosk` |
55+
| Can't reach server | Check Pi can ping SERVER_IP |
56+
| Logs | `journalctl -u display-kiosk -f` |
57+
58+
## Updating
59+
60+
### Server
3661
```bash
37-
sudo /opt/display-node/update.sh
62+
git pull && ./scripts/deploy.sh
3863
```
3964

40-
## Troubleshooting
41-
42-
| Issue | Solution |
43-
|-------|----------|
44-
| Pi screen black | `sudo systemctl restart display-kiosk` |
45-
| Display not updating | Check logs: `journalctl -u display-kiosk -f` |
46-
| Server down | `docker compose -f deploy/docker-compose.yml up -d` |
65+
### Pi
66+
Pi auto-checks hourly. Force: `sudo /opt/display-node/update.sh`

pi-node/health-monitor.sh

Lines changed: 0 additions & 65 deletions
This file was deleted.

pi-node/kiosk.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#!/usr/bin/env bash
2-
# ============================================================
32
# Kiosk Mode — Launch Chromium in fullscreen
4-
# ============================================================
53
set -euo pipefail
64

75
source /opt/display-node/config.env
86

7+
# Derive display URL from SERVER_URL + FLOOR_ID
8+
DISPLAY_URL="${SERVER_URL}/display/${FLOOR_ID}"
9+
910
# Wait for X server
1011
while ! xdpyinfo -display :0 &>/dev/null; do
1112
sleep 1

0 commit comments

Comments
 (0)