A smart, tile-based dashboard for Raspberry Pi (and any Linux/macOS machine). Glassmorphic draggable/resizable widgets, real-time data via WebSocket, lofi ASCII art vibes.
┌────────┬────────┬────────┬────────┐
│ Clock │ Lofi │Weather │ System │
├────────┴──┬─────┴──┬─────┴────────┤
│ Cricket │ News │ Trending │
├───────────┴────────┴──────────────┤
│ GitHub Activity │
└───────────────────────────────────┘
- Python 3.10+
- Node.js 18+ (with npm)
- Git
git clone <your-repo-url> && cd GlanceOS
chmod +x setup.sh
./setup.shThis creates a Python venv, installs all dependencies, creates backend/.env, and prompts for API keys plus Google Calendar connection details during setup.
It also creates frontend/.env and configures frontend backend/WS connection variables.
For non-interactive installs, export keys before running setup:
export WEATHER_API_KEY="your_openweathermap_key"
export GITHUB_TOKEN="your_github_token"
export TODOIST_API_TOKEN="your_todoist_token"
export GOOGLE_CALENDAR_ICS_URL="your_google_calendar_ics_url"
export NEWS_LLM_API_KEY="your_gemini_key"
export VITE_BACKEND_URL="http://127.0.0.1:8000"
export VITE_WS_URL="ws://127.0.0.1:8000/ws"
export VITE_PROXY_API_TARGET="http://127.0.0.1:8000"
export VITE_PROXY_WS_TARGET="ws://127.0.0.1:8000"
export VITE_DISABLE_PROXY="false"
./setup.shWhen you run the backend with python run.py, GlanceOS checks missing service credentials and prompts interactively (one-time) for:
WEATHER_API_KEYGITHUB_TOKENTODOIST_API_TOKENNEWS_LLM_API_KEY(also auto-detected fromGEMINI_API_KEY/GOOGLE_API_KEY)- Google Calendar config:
GOOGLE_CALENDAR_ICS_URLorGOOGLE_CALENDAR_ID+GOOGLE_CALENDAR_API_KEY
Entered values are persisted to backend/.env.
Then start both services:
# Terminal 1 — Backend
cd backend
source venv/bin/activate
python run.py
# Terminal 2 — Frontend
cd frontend
npm run devOpen http://localhost:5173 in your browser.
If you prefer to do it step by step:
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then edit .env with your keys
python run.pyThe API server starts at http://localhost:8000.
cd frontend
npm install
npm run devThe dashboard starts at http://localhost:5173 and proxies API/WebSocket requests to the backend.
setup.sh now asks for API keys and writes them to backend/.env.
You can still edit backend/.env manually:
| Variable | Description | Required |
|---|---|---|
WEATHER_API_KEY |
OpenWeatherMap API key | No* |
GITHUB_TOKEN |
GitHub personal access token | No* |
CRICKET_API_KEY |
CricketData/CricAPI key | No* |
TODOIST_API_TOKEN |
Todoist API token | No |
GOOGLE_CALENDAR_ICS_URL |
Google Calendar ICS URL (private/public calendars) | No |
GOOGLE_CALENDAR_ID |
Google Calendar ID for API mode | No |
GOOGLE_CALENDAR_API_KEY |
Google Calendar API key for API mode | No |
NEWS_LLM_API_KEY |
API key for LLM-based News crux summaries | No |
NEWS_USE_LLM |
Enable/disable News LLM summaries (true/false) |
No |
NEWS_LLM_PROVIDER |
LLM provider (gemini default) |
No |
NEWS_LLM_BASE_URL |
LLM base URL (default Gemini API) | No |
NEWS_LLM_MODEL |
LLM model for News summaries (default gemini-2.0-flash-lite) |
No |
WEATHER_CITY |
Default weather city (e.g. Hyderabad,IN) | No |
GITHUB_USERNAME |
GitHub username for activity widget | No |
CRICKET_TIMEZONE |
Cricket schedule timezone (default Asia/Kolkata) |
No |
HOST |
Backend bind address (default 0.0.0.0) |
No |
PORT |
Backend port (default 8000) |
No |
LOG_LEVEL |
Backend log verbosity (default WARNING) |
No |
*Widgets show offline/unavailable states when required live data cannot be fetched.
Get your keys:
- Weather: https://openweathermap.org/api (free tier)
- GitHub: https://github.com/settings/tokens (no scopes needed for public data)
- Cricket: https://cricketdata.org/signup.aspx (free plan available)
- Todoist: https://app.todoist.com/app/settings/integrations/developer
- News LLM (optional): Gemini API key from Google AI Studio
- Google Calendar:
- Recommended: Google Calendar Settings -> Integrate calendar -> Secret address in iCal format -> set
GOOGLE_CALENDAR_ICS_URL- Alternative: enable Google Calendar API and setGOOGLE_CALENDAR_ID+GOOGLE_CALENDAR_API_KEY
| Widget | Data Source | Update Interval |
|---|---|---|
| Clock | Client-side | 1s |
| Lofi Art | ASCII scenes (local) | 12s cycle |
| Weather | OpenWeatherMap API | 10 min |
| System | psutil (CPU/RAM/Disk) | 3s |
| Cricket | ESPN / CricAPI | Auto every 10 min from 19:30-23:30 + final call at 00:00 |
| News | Hacker News + Google RSS + article-content summaries | 15 min |
| Trending | GitHub Trending | 30 min |
| GitHub | GitHub Events API | 5 min |
| Calendar | Google Calendar (ICS/API) | 5 min |
| Todo | Todoist Inbox + sections (nested tasks) | 2 min |
All widgets are draggable and resizable. Layouts persist in localStorage.
Frontend (React + Tailwind + Vite)
│
WebSocket / REST
│
Backend (Python FastAPI + APScheduler)
│
Linux OS layer (psutil, systemd)
- Frontend: React 19, Tailwind CSS v4, react-grid-layout, Framer Motion
- Backend: FastAPI, APScheduler, httpx, psutil, WebSockets
- Data flow: Backend polls APIs on schedule → caches results → pushes via WebSocket → frontend renders
# Install the backend as a systemd service
sudo cp deploy/glanceos-backend.service /etc/systemd/system/
sudo systemctl enable --now glanceos-backend
# Build the frontend for production (served by FastAPI at :8000)
cd frontend
npm run build
# Launch Chromium in kiosk mode
chmod +x deploy/kiosk.sh
deploy/kiosk.shProduction URL: http://localhost:8000
GlanceOS/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI app entrypoint
│ │ ├── config.py # Pydantic settings (.env)
│ │ ├── ws_manager.py # WebSocket connection manager
│ │ ├── scheduler.py # APScheduler jobs
│ │ ├── routers/
│ │ │ ├── api.py # REST endpoints
│ │ │ └── ws.py # WebSocket endpoint
│ │ └── services/
│ │ ├── system_monitor.py
│ │ ├── weather.py
│ │ ├── github.py
│ │ ├── cricket.py
│ │ ├── news.py
│ │ ├── trending.py
│ │ └── lofi.py
│ ├── run.py
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── App.jsx
│ │ ├── index.css
│ │ ├── components/
│ │ │ ├── Dashboard.jsx
│ │ │ ├── WidgetCard.jsx
│ │ │ └── widgets/ # All widget components
│ │ ├── hooks/useWebSocket.js
│ │ └── context/ThemeContext.jsx
│ └── vite.config.js
├── deploy/
│ ├── glanceos-backend.service
│ └── kiosk.sh
├── setup.sh
└── .gitignore
MIT