Files
Calender/README.md
Ludwig Mey ef4ffbbf5d Fix weather icons, forecast temps, and update docs
- Replace emoji weather icons with OWM icon images to fix rendering
  issues on Linux displays (e.g.  showing as a rectangle)
- Fix forecast daily max/min to use true high/low across all 3-hour
  slots instead of just the first entry of the day
- Update README: correct BACKGROUND interval (60 min), update kiosk
  setup for labwc/Wayland, add restart-calendar.sh instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 21:56:27 +13:00

8.7 KiB

Family Calendar Display

A smart display application for Raspberry Pi that shows time, weather, calendar events, and rotating background images.

Project created: February 14, 2026

Features

  • 🕐 Real-time Clock - Current time and date display
  • 🌤️ Weather - Current weather and 3-day forecast (OpenWeatherMap)
  • 📅 Google Calendar - Calendar events display (supports public iCal feeds)
  • 🖼️ Rotating Backgrounds - Beautiful images from local directory
  • 🎨 Dynamic Text Color - Automatically adjusts text color based on background brightness
  • 😄 Dad Jokes - Random jokes to brighten your day (optional)

Requirements

  • Python 3.8+
  • Raspberry Pi (tested on Pi 3/4) or any Linux system
  • Google Calendar API credentials
  • OpenWeatherMap API key (free tier)

Quick Start

1. Clone the Repository

git clone ssh://git@gitea.meyfamily.co.nz:2222/luddie/Calender.git
cd Calender

2. Install Dependencies

python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -r requirements.txt

3. Configure Environment Variables

cp .env.example .env

Edit .env and add your API keys:

# Get your OpenWeatherMap API key from: https://openweathermap.org/api
OPENWEATHER_API_KEY=your_api_key_here

# Your Google Calendar ID (found in Google Calendar settings)
GOOGLE_CALENDAR_ID=your_calendar_id@group.calendar.google.com

# Generate a secret key for Flask
FLASK_SECRET_KEY=your_random_secret_key

4. Get OpenWeatherMap API Key

  1. Go to OpenWeatherMap
  2. Sign up for a free account
  3. Navigate to "API keys" section
  4. Copy your API key
  5. Add it to your .env file as OPENWEATHER_API_KEY

Find Your Location Coordinates:

  1. Go to LatLong.net
  2. Search for your city
  3. Copy the latitude and longitude values
  4. Add them to your .env file as WEATHER_LAT and WEATHER_LON

5. Set Up Google Calendar

Option 1: Public iCal Feed (Easiest - No Authentication)

  1. Open Google Calendar
  2. Go to Settings (⚙️ gear icon)
  3. Select the calendar you want to display
  4. Scroll down to "Integrate calendar"
  5. Copy the "Public URL to this calendar" in iCal format
    • The URL looks like: https://calendar.google.com/calendar/ical/...@group.calendar.google.com/public/basic.ics
  6. Add this URL to your .env file as GOOGLE_CALENDAR_ICAL_URL
  7. Also copy the Calendar ID (looks like abc123...@group.calendar.google.com)
  8. Add it to your .env file as GOOGLE_CALENDAR_ID

Note: Your calendar must be set to "Public" for this method to work.

Option 2: Google Calendar API with Credentials (Advanced)

If you prefer to use private calendars with authentication:

  1. Go to Google Cloud Console
  2. Create a new project or select existing one
  3. Enable the Google Calendar API
  4. Create credentials (Service Account)
  5. Download the credentials JSON file
  6. Save it as credentials/google_calendar_credentials.json
  7. Share your calendar with the service account email

6. Add Background Images

Place your images in the static/backgrounds/ directory:

cp /path/to/your/images/*.jpg static/backgrounds/

Supported formats: JPG, JPEG, PNG, GIF, WebP

Recommended specifications:

  • Resolution: 1920x1080 or higher
  • Aspect ratio: 16:9 (for full-screen displays)
  • File size: Keep under 5MB for faster loading

Changing Image Rotation Interval:

Edit static/js/app.js:

const INTERVALS = {
    BACKGROUND: 3600000,  // Milliseconds (3600000 = 60 minutes)
    ...
};

7. Run the Application

python app.py

Visit http://localhost:5000 in your browser.

Raspberry Pi Deployment

Auto-start Flask Application

Create a systemd service:

sudo nano /etc/systemd/system/calendar-display.service

Add the following content:

[Unit]
Description=Calendar Display Flask App
After=network.target

[Service]
User=pi
WorkingDirectory=/home/pi/Calender
ExecStart=/home/pi/Calender/venv/bin/python app.py
Restart=always
Environment="PATH=/home/pi/Calender/venv/bin"

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable calendar-display.service
sudo systemctl start calendar-display.service

Configure Chromium Kiosk Mode

The Pi uses labwc (Wayland). Create the autostart entry:

mkdir -p ~/.config/autostart
nano ~/.config/autostart/chromium-kiosk.desktop

Add the following:

[Desktop Entry]
Type=Application
Name=Chromium Kiosk
Exec=chromium-browser --ozone-platform=wayland --kiosk --noerrdialogs --incognito --disable-infobars --simulate-touch-screen --force-show-cursor http://localhost:5002
X-GNOME-Autostart-enabled=true

Reboot

sudo reboot

The display should now start automatically on boot!

Restarting Without Rebooting

A helper script is included to restart both the Flask service and the Chromium kiosk without rebooting:

bash ~/restart-calendar.sh

This will:

  1. Restart the calendar-display systemd service
  2. Kill and relaunch Chromium in the correct Wayland session

Configuration

Environment Variables (.env file)

Weather Settings:

  • OPENWEATHER_API_KEY - Your OpenWeatherMap API key
  • WEATHER_LOCATION - City name and country code (e.g., "London,UK")
  • WEATHER_LAT - Latitude of your location
  • WEATHER_LON - Longitude of your location

Calendar Settings:

  • GOOGLE_CALENDAR_ID - Your calendar ID
  • GOOGLE_CALENDAR_ICAL_URL - Public iCal feed URL (easiest method)
  • CALENDAR_DAYS_AHEAD - Number of days ahead to show events (default: 5)

Update Intervals (in seconds):

  • WEATHER_UPDATE_INTERVAL - Weather refresh interval (default: 900)
  • CALENDAR_UPDATE_INTERVAL - Calendar refresh interval (default: 300)
  • JOKE_UPDATE_INTERVAL - Dad joke refresh interval (default: 3600)

Other:

  • FLASK_SECRET_KEY - Flask session secret key

JavaScript Configuration (static/js/app.js)

For more precise control over update intervals, edit the INTERVALS object:

const INTERVALS = {
    TIME: 1000,              // 1 second
    WEATHER: 900000,         // 15 minutes
    CALENDAR: 300000,        // 5 minutes
    BACKGROUND: 3600000,     // 60 minutes
    JOKE: 3600000            // 1 hour
};

To change image rotation time:

  1. Open static/js/app.js
  2. Find the INTERVALS object at the top
  3. Change BACKGROUND to your desired value in milliseconds
    • 300000 = 5 minutes
    • 1800000 = 30 minutes
    • 3600000 = 60 minutes (default)

Project Structure

Calender/
├── app.py                      # Main Flask application
├── config.py                   # Configuration management
├── requirements.txt            # Python dependencies
├── .env                        # Environment variables (create from .env.example)
├── .env.example               # Environment template
├── static/
│   ├── css/style.css          # Styling
│   ├── js/app.js              # Frontend JavaScript
│   └── backgrounds/           # Background images directory
├── templates/
│   └── index.html             # Main display template
└── credentials/
    └── google_calendar_credentials.json  # Google API credentials

API Endpoints

  • GET / - Main display page
  • GET /api/weather - Weather data (cached for 15 min)
  • GET /api/calendar - Calendar events (cached for 5 min)
  • GET /api/background - Random background image
  • GET /api/joke - Dad joke (cached for 1 hour)

Troubleshooting

Weather not loading

  • Check your OpenWeatherMap API key is valid
  • Ensure you're not exceeding the free tier rate limits (60 calls/min)

Calendar not loading

  • Verify Google Calendar API credentials are set up correctly
  • Check the calendar ID is correct
  • Ensure the service account has access to the calendar

Display not starting on boot

  • Check systemd service status: sudo systemctl status calendar-display.service
  • View logs: sudo journalctl -u calendar-display.service -f

Background images not showing

  • Ensure images are in static/backgrounds/
  • Check file permissions: chmod 644 static/backgrounds/*

Contributing

Feel free to submit issues or pull requests!

License

MIT License - Feel free to use and modify for personal use.

Credits

Built with: