I have a 2 line by 16 character LCD display with a I2C interface. I wanted to use it as a clock and date display which also could display the current weather.
![]() |
Date and Time Display |
![]() |
Weather Display |
![]() |
Rapsberry Pi 5 clock/weather |
You will need an API key to open weather openweatherapi. Put your api key in an .env file as openweathermapapikey=yourkey. The python script uses the dotenv library to read this and use your API key. This is a free service with usage limitations. You will need to change the parameters to the open weather API to use you city and units.
params = {
"q": "Etobicoke,Ontario,CA",
"units": "metric", # For Celsius
"appid": OPENWEATHERMAPAPIKEY # API key
}
#!/usr/bin/env python3"""lcd_weatherclock.py - A program that displays a clock on an LCD screenand shows weather information for 10 seconds when a button is pressed."""from LCD import LCDimport datetimeimport timeimport requestsimport osfrom dotenv import load_dotenvfrom gpiozero import Buttonimport threading# Load environment variables from .env fileload_dotenv()# Initialize LCDlcd = LCD(2, 0x27, True)lcd.clear()# Initialize button with debouncebutton = Button(21, pull_up=True, bounce_time=0.2) # 200ms debounce time# Global variablesdisplay_mode = "clock" # Can be "clock" or "weather"weather_timer = Nonedef get_etobicoke_weather():"""Get current weather for Etobicoke, Ontario, Canada using OpenWeatherMap API"""try:# OpenWeatherMap API endpoint for current weatherurl = "https://api.openweathermap.org/data/2.5/weather"# Get APP ID for weather apiOPENWEATHERMAPAPIKEY = os.getenv("openweathermapapikey")# Parameters for Etobicoke, Ontario, Canadaparams = {"q": "Etobicoke,Ontario,CA","units": "metric", # For Celsius"appid": OPENWEATHERMAPAPIKEY # API key}# Make the API requestresponse = requests.get(url, params=params)# Check if the request was successfulif response.status_code == 200:# Parse the JSON responseweather_data = response.json()# Extract relevant informationtemperature = weather_data["main"]["temp"]condition = weather_data["weather"][0]["main"]humidity = weather_data["main"]["humidity"]return {"temperature": temperature,"condition": condition,"humidity": humidity}else:return {"error": f"API Error: {response.status_code}"}except Exception as e:return {"error": f"Error: {str(e)}"}def display_weather(lcd):"""Display weather data on the LCD"""global display_mode# Set display mode to weatherdisplay_mode = "weather"# Show loading messagelcd.clear()lcd.message("Weather...")# Get weather dataweather_data = get_etobicoke_weather()lcd.clear()if "error" in weather_data:lcd.message("Weather Error")lcd.message(weather_data["error"][:16], 2) # Truncate to fit LCD widthelse:# Format and display weather informationtemp_str = f"Temp: {weather_data['temperature']:.1f}C"cond_str = f"{weather_data['condition']} {weather_data['humidity']}%"lcd.message(temp_str)lcd.message(cond_str, 2)# Set a timer to switch back to clock after 10 secondsglobal weather_timerif weather_timer:weather_timer.cancel()weather_timer = threading.Timer(10.0, switch_to_clock)weather_timer.start()def switch_to_clock():"""Switch display back to clock mode"""global display_modedisplay_mode = "clock"# The main loop will update the display on the next iterationdef display_clock(lcd, force_update=False):"""Display clock on the LCD"""now = datetime.datetime.now()currenttime = now.strftime("%H:%M:%S")currentdate = now.strftime("%d-%m-%Y")# Only update if time/date changed or force update is requestedif force_update or currenttime != display_clock.lasttime or currentdate != display_clock.lastdate:lcd.clear()lcd.message('%02d:%02d:%02d' % (now.hour, now.minute, now.second), 1)lcd.message('%02d-%02d-%04d' % (now.day, now.month, now.year), 2)display_clock.lasttime = currenttimedisplay_clock.lastdate = currentdate# Initialize static variables for display_clock functiondisplay_clock.lasttime = ''display_clock.lastdate = ''def button_pressed():"""Function called when button is pressed"""global display_modeif display_mode == "clock":display_weather(lcd)# Assign callback function to button press eventbutton.when_pressed = button_pressed# Display welcome messagelcd.message("Weather Clock")lcd.message("Starting...", 2)time.sleep(2)lcd.clear()# Main looptry:while True:if display_mode == "clock":display_clock(lcd)time.sleep(0.1)except KeyboardInterrupt:# Clean up on exitif weather_timer:weather_timer.cancel()lcd.clear()print("\nExiting program")