A realistic sky ceiling projector with weather effects, celestial objects, and enhanced starfield
Project description
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! 🌌
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sky_ceiling_projector-1.0.0.tar.gz.
File metadata
- Download URL: sky_ceiling_projector-1.0.0.tar.gz
- Upload date:
- Size: 88.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f61b635cfdb089f84902ff41abfb16ba0ab268e25f21313c0798c51943738a94
|
|
| MD5 |
73b3d1c45a3d4cd1cdae3da88a2b1bc4
|
|
| BLAKE2b-256 |
0c9d5a4c810862635092a6bfd6e625e653202155aebe93df2da92923f11cbe4f
|
Provenance
The following attestation bundles were made for sky_ceiling_projector-1.0.0.tar.gz:
Publisher:
publish.yml on baileytec-labs/live-ceiling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sky_ceiling_projector-1.0.0.tar.gz -
Subject digest:
f61b635cfdb089f84902ff41abfb16ba0ab268e25f21313c0798c51943738a94 - Sigstore transparency entry: 268095973
- Sigstore integration time:
-
Permalink:
baileytec-labs/live-ceiling@660121ffcde233be736680a8f73ce28a0f5a2fc4 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/baileytec-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@660121ffcde233be736680a8f73ce28a0f5a2fc4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sky_ceiling_projector-1.0.0-py3-none-any.whl.
File metadata
- Download URL: sky_ceiling_projector-1.0.0-py3-none-any.whl
- Upload date:
- Size: 30.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fbe9260a2b29b0436939df346bab14f2aecc8eec25e67559096fa8c3c8cebfaf
|
|
| MD5 |
796859b8c1f5954fa9e43612a0546a36
|
|
| BLAKE2b-256 |
84ff4874e5c51d92b4f5e9be1dfbacbd0b39880b037b19cf4384764f7e2ad611
|
Provenance
The following attestation bundles were made for sky_ceiling_projector-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on baileytec-labs/live-ceiling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sky_ceiling_projector-1.0.0-py3-none-any.whl -
Subject digest:
fbe9260a2b29b0436939df346bab14f2aecc8eec25e67559096fa8c3c8cebfaf - Sigstore transparency entry: 268095985
- Sigstore integration time:
-
Permalink:
baileytec-labs/live-ceiling@660121ffcde233be736680a8f73ce28a0f5a2fc4 -
Branch / Tag:
refs/tags/v1.0.3 - Owner: https://github.com/baileytec-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@660121ffcde233be736680a8f73ce28a0f5a2fc4 -
Trigger Event:
push
-
Statement type: