Generates a 480×800px greyscale PNG for an e-ink display, updated hourly via Google Cloud Run. The image is served from a public GCS bucket at an unguessable UUID path.
Header — day of week + date in Czech, name day from svatkyapi.cz
Weather forecast — 4 time slots (data from met.no):
Birthdays — next 3 upcoming birthdays with date, age, and days until. Today’s birthday gets a special highlight. Data loaded from a secret gist (see below).
Lunch — today’s or next school day’s meal from Schildkröte, scraped after login.
Footer — sunrise, day length (with ±diff vs yesterday), sunset
Cloud Scheduler (hourly)
→ Cloud Run Job
fetches weather + name day APIs
renders HTML → PNG via headless Chromium
uploads to GCS
→ GCS bucket (public-read)
← e-ink device polls every hour
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
playwright install chromium
python main.py
# output: dashboard.png
Runs locally without any GCP credentials — saves dashboard.png to disk.
gcloud auth login && gcloud config set project $PROJgcloud services enable run.googleapis.com cloudbuild.googleapis.com \
cloudscheduler.googleapis.com storage.googleapis.com \
containerregistry.googleapis.com --project=$PROJ
gcloud auth configure-docker gcr.ioCopy .env.example to .env and fill in your values:
PROJ=your-gcp-project-id
BUCKET_NAME=your-bucket-name
FEED_ID=your-uuid # generate with: python3 -c "import uuid; print(uuid.uuid4())"
.env is gitignored and never committed.
Birthday data is stored in a secret GitHub Gist as birthdays.json (see birthdays.json.example for the format). Add the raw gist URL to .env:
BIRTHDAYS_GIST_URL=https://gist.githubusercontent.com/you/abc123/raw/birthdays.json
Use the versionless /raw/<filename> URL (no commit hash) so updates to the gist are picked up automatically. The script fetches the gist at startup; if the URL is absent, the birthday section is simply empty.
./deploy.sh
Sets up the bucket, service account, IAM roles, builds + pushes the Docker image, deploys the Cloud Run Job, and creates the hourly Cloud Scheduler trigger.
./redeploy.sh
Rebuilds the image using local Docker layer cache (fast — only the code layer rebuilds), pushes, updates the job, and triggers a test run.
| Package | Purpose |
|---|---|
requests |
API calls |
astral |
Sunrise/sunset calculation |
playwright |
Headless Chromium screenshot |
google-cloud-storage |
GCS upload |