live-ceiling – Bring the Real-Time Sky Indoors
update: You can now install this using pip install sky-ceiling-projector!
Live-ceiling turns a Raspberry Pi Zero 2 W and any HDMI projector into a miniature planetarium that shows a weather-accurate, time-accurate sky for any city in the world—complete with stars, Moon phases, planets, shooting stars, clouds, rain, snow, lightning, and smooth colour transitions when you “fly” to another location. All data comes from free, no-key public APIs, so the setup can run indefinitely with nothing more than Wi-Fi.
✨ Key Features
-
Real-time sky gradient that matches local dawn, day, sunset, dusk and night.
-
Accurate weather effects powered by Open-Meteo’s Geocoding and Forecast APIs—no API key required. open-meteo.comopen-meteo.comopen-meteo.com
-
Detailed celestial objects: variable stars, red/blue giants, Milky Way band, realistic Moon with pre-generated craters, Sun with sunspots, planets, satellites and meteor showers.
-
Weather-sensitive particles for rain, drizzle, snow and fog, plus branching lightning during thunderstorms.
-
Demo-mode “world tour” that cycles through famous cities on a timer (or on key-press) with a 5-second cross-fade.
-
Optimised for Raspberry Pi Zero 2 W (quad-core 1 GHz, 512 MB RAM) so it runs smoothly at 1080p/30 FPS. datasheets.raspberrypi.comwired.com
-
Pygame full-screen output with double-buffering and hardware surfaces for tear-free projection. stackoverflow.com
-
Zero-cost libraries only:
pygame,numpy,requests,geopy,timezonefinder, andpytz.
🛠️ Bill of Materials
| Item | Notes |
|---|---|
| Raspberry Pi Zero 2 W | Any Pi works, but Zero 2 W is the smallest that can sustain 30 FPS. datasheets.raspberrypi.com |
| micro-SD card (16 GB +) | Flash the latest Raspberry Pi OS Lite. |
| Official Pi Zero camera/power adapter kit or 5 V/2 A USB power | The projector’s USB-A port usually provides enough current. |
| HDMI cable (micro-HDMI → HDMI) | Connects Pi to projector. Basic passive cables work. fromdev.com |
| Any HDMI projector (720p–1080p) | Short-throw or ceiling-mounted mini projectors work best. |
| Wi-Fi connection | Required only for live weather; sky still renders offline. |
Tip: If your projector only has VGA, use an inexpensive HDMI→VGA adapter and enable hdmi_safe=1 in /boot/config.txt. ask.tvsbook.com
📦 Software Requirements
| Package | Install command | Purpose |
|---|---|---|
| Python 3.7 + | sudo apt install python3 python3-pip |
Interpreter |
| pygame ≥ 2.1 | sudo pip3 install pygame |
Rendering layer on Pi. github.com |
| numpy, requests | pip3 install numpy requests |
Math & HTTP |
| geopy | pip3 install geopy |
Fallback geocoder. gis.stackexchange.com |
| timezonefinder, pytz | pip3 install timezonefinder pytz |
Local-time conversion. pypi.org |
🔧 Installation
bash
CopyEdit
# 1. Flash Raspberry Pi OS (Lite or Desktop) to SD and boot.
# 2. Enable SSH & Wi-Fi using raspi-config if needed.
sudo apt update && sudo apt upgrade -y
# 3. Install SDL dependencies for pygame
sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libfreetype6-dev libatlas-base-dev -y
# 4. Clone the repo
git clone https://github.com/your-user/live-ceiling.git
cd live-ceiling
# 5. Install Python deps
pip3 install -r requirements.txt
# 6. (Optional) Test pygame opens in full-screen
python3 - << 'PY'
import pygame, sys
pygame.init(); pygame.display.set_mode((0,0), pygame.FULLSCREEN); pygame.time.wait(2000); sys.exit()
PY
If the screen stays black after step 6, verify HDMI-0 is enabled and the projector is on the correct input. raspberrypi.stackexchange.com
🚀 Running the Projector
bash
CopyEdit
# Basic: simulate current sky over Paris
python3 live-ceiling.py --location "Paris, France"
# High-performance preset for 480 p pico-projectors
python3 live-ceiling.py --preset performance --location "Tokyo, Japan"
# Demo mode: world tour every 5 min
python3 live-ceiling.py --cycle-cities --cycle-interval 300
Keyboard Controls
| Key | Action |
|---|---|
| ESC | Quit |
| I | Toggle info overlay |
| D | Debug mode (cycles weather) |
| R | Regenerate starfield |
| SPACE | Trigger lightning (only if weather = thunderstorm) |
| N | Next city (demo mode) |
⚙️ Configuration & Customisation
| Flag | Default | Description |
|---|---|---|
--preset |
balanced |
performance (≤ 15 fps), balanced (default), quality (> 20 fps on Pi 4) |
--location |
required | City or “City, State/ISO-Country”. Uses Open-Meteo geocoder. open-meteo.com |
--cycle-cities & --cycle-interval |
– | Rotate through a curated list of major cities. |
--no-info |
off | Hide FPS, weather and location overlay. |
To add your own city list, edit WORLD_CITIES in the script.
🏎️ Performance Tips
-
Run headless Raspberry Pi OS Lite to free RAM.
-
Use the
performancepreset for 720 p or lower projectors; it halves star and particle counts. -
Disable glow effects by setting
"enable_glow": FalseinsideQUALITY_SETTINGS. -
To force 30 FPS, add
pygame.time.Clock().tick(30)inside the main loop (already set). -
For multiple projectors, add an HDMI splitter; the Pi outputs the same frame to all displays. reddit.com
🩻 How It Works (Quick Tech Peek)
| Component | Library/API | Notes |
|---|---|---|
| Geocoding | Open-Meteo Geocoding (primary) → Geopy + Nominatim fallback | No key, fast, returns local timezone. open-meteo.comgis.stackexchange.com |
| Weather | Open-Meteo “current_weather” endpoint | Supplies weather_code, cloud_cover, temperature, wind. open-meteo.com |
| Local time | TimezoneFinder + pytz for offline TZ lookup | Works without internet after first run. pypi.org |
| Rendering | Pygame 2 HW surfaces, double buffer | Full-screen toggle example: see StackOverflow. stackoverflow.com |
| Hardware | Pi Zero 2 W (quad-core A53 @ 1 GHz, 512 MB RAM) | Small, silent, $15. datasheets.raspberrypi.comwired.com |
| Display | HDMI out to projector | Any modern HDMI projector or TV works. fromdev.com |
APIs are free for non-commercial use; Open-Meteo imposes reasonable request rate limits (60 calls/min). open-meteo.com
🐛 Troubleshooting
| Symptom | Fix |
|---|---|
| Black screen on boot | Ensure projector input is HDMI #; add hdmi_safe=1 in /boot/config.txt if using adapters. ask.tvsbook.com |
| “pygame.error: No available video device” | Run with a screen attached or set export SDL_VIDEODRIVER=fbcon. |
| Weather always “Loading…” | Check internet; Open-Meteo requires outbound HTTPS port 443. |
| Wrong local time | Disable Wi-Fi power save (iw dev wlan0 set power_save off) and verify TZ in raspi-config. |
| Frame-rate dips below 20 FPS | Switch to --preset performance, close other processes, lower resolution to 720 p in /boot/config.txt. |
🤝 Acknowledgements
-
Open-Meteo – free weather & geocoding APIs. open-meteo.comopen-meteo.comopen-meteo.com
-
Pygame – SDL-based cross-platform game library. github.com
-
Geopy / Nominatim (OSM) – geocoding fallback. gis.stackexchange.com
-
TimezoneFinder & pytz – offline timezone look-ups. pypi.org
-
Raspberry Pi Foundation for the Pi Zero 2 W hardware. datasheets.raspberrypi.com
📄 License
This project is licensed under the MIT License (see LICENSE).
Happy sky-gazing! 🌌
Release files for sky-ceiling-projector 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sky_ceiling_projector-1.0.0.tar.gz | 88.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sky_ceiling_projector-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 119.2 kB
Release files / sky_ceiling_projector-1.0.0.tar.gz
| Download URL | sky_ceiling_projector-1.0.0.tar.gz |
|---|---|
| Size | 88.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f61b635cfdb089f84902ff41abfb16ba0ab268e25f21313c0798c51943738a94
|
|
BLAKE2b-256 checksum How to use checksums |
0c9d5a4c810862635092a6bfd6e625e653202155aebe93df2da92923f11cbe4f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 8, 2025.
Transparency logRelease files / sky_ceiling_projector-1.0.0-py3-none-any.whl
| Download URL | sky_ceiling_projector-1.0.0-py3-none-any.whl |
|---|---|
| Size | 30.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fbe9260a2b29b0436939df346bab14f2aecc8eec25e67559096fa8c3c8cebfaf
|
|
BLAKE2b-256 checksum How to use checksums |
84ff4874e5c51d92b4f5e9be1dfbacbd0b39880b037b19cf4384764f7e2ad611
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 8, 2025.
Transparency log