Project Overview:
This project is a weather station built using the UniHiker board, which displays real-time weather data retrieved from the OpenWeatherMap API. It fetches weather information based on the geographic coordinates (latitude and longitude) of a city and shows it on the UniHiker's screen. The data includes weather conditions such as temperature, humidity, wind speed, and an icon representing the current weather.
The weather data is updated every 10 minutes to ensure the display remains current.
Key Components:
OpenWeatherMap API: This service provides the real-time weather data in JSON format. The API call requires an API key and the geographic coordinates (latitude and longitude) of the location for which the weather data is requested.
UniHiker: A microcontroller board that features a display, used in this project to visually present the weather data. The board's gui module is utilized to display text and images on the screen.
Weather Icons: Weather condition IDs returned by the API are mapped to specific weather icons (PNG images), which are displayed on the screen to represent different weather conditions visually (e.g., sunny, cloudy, rainy).
Temperature, Humidity, Wind Speed: These weather details are extracted from the API response and displayed alongside the weather icon to provide a comprehensive weather overview.
Creating an account on OpenWeatherMap and generating an API token is a simple process. First, visit OpenWeatherMap and click on the "Sign Up" button in the top right corner. Fill in your email address and a secure password, accept the terms of service, and click "Sign Up." After signing up, check your email for a confirmation link and click it to verify your account.
Once your account is verified, log in to OpenWeatherMap. Navigate to your account settings by clicking your username or profile icon, then select "My API keys." Here, you will find a default API key. To create a new one, click "Create" or "Add API key." Enter a name for your API key (e.g., "Weather Station") and click "Generate."
After the key is created, copy it for use in your application.
Icons can be downloaded from OpenWeatherMap or you can create your own weather icons. They must be placed in icons folder and icon names must match following scheme.
"01": "icons/[email protected]", # Clear sky
"02": "icons/[email protected]", # Few clouds
"03": "icons/[email protected]", # Scattered clouds
"04": "icons/[email protected]", # Broken clouds
"09": "icons/[email protected]", # Shower rain
"10": "icons/[email protected]", # Rain
"11": "icons/[email protected]", # Thunderstorm
"13": "icons/[email protected]", # Snow
"50": "icons/[email protected]", # Mist
Icons are also available:
https://github.com/rodrigokamada/openweathermap
import time
import requests # Using the requests library to fetch data from OpenWeatherMap API
from unihiker import GUI # Importing gui for drawing on the UniHiker screen
screen = GUI() # Instantiate the GUI class
# Function to fetch weather data from OpenWeatherMap API
def get_weather(api_key, lat, lon):
"""
Fetches weather data from OpenWeatherMap API using the provided API key and geographic coordinates.
Args:
api_key (str): Your OpenWeatherMap API key.
lat (str): Latitude of the location.
lon (str): Longitude of the location.
Returns:
dict: A dictionary containing weather data in JSON format.
"""
api_url = f'http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={api_key}&units=metric'
response = requests.get(api_url)
data = response.json() # Parse the JSON response to a Python dictionary
return data # Return the weather data
# Function to map weather conditions to corresponding icon images
def get_weather_icon(weather_id):
"""
Maps weather condition IDs from the API to the corresponding PNG icon file paths.
Args:
weather_id (int): The weather condition ID provided by the API.
Returns:
str: The file path to the weather icon PNG.
"""
# Dictionary that maps weather condition codes to file paths of corresponding icons
icon_map = {
"01": "icons/[email protected]", # Clear sky
"02": "icons/[email protected]", # Few clouds
"03": "icons/[email protected]", # Scattered clouds
"04": "icons/[email protected]", # Broken clouds
"09": "icons/[email protected]", # Shower rain
"10": "icons/[email protected]", # Rain
"11": "icons/[email protected]", # Thunderstorm
"13": "icons/[email protected]", # Snow
"50": "icons/[email protected]", # Mist
}
# Extract the first two digits of the weather ID (e.g., "01" for clear sky)
weather_code = str(weather_id)[0:2]
# Return the file path to the corresponding icon, or a default icon if the ID is not in the map
return icon_map.get(weather_code, "icons/default.png")
# Function to display weather data on the UniHiker screen using the gui module
def display_weather(data, city):
screen.clear()
# Extract relevant weather data
weather = data['weather'][0]['description']
temperature = data['main']['temp']
humidity = data['main']['humidity']
wind_speed = data['wind']['speed']
weather_id = data['weather'][0]['id'] # Weather condition ID
# Get the appropriate weather icon file path
weather_icon_path = get_weather_icon(weather_id)
# Load and display the weather icon
weather_icon = weather_icon_path
screen.draw_image(x=0, y=0, w=80, h=80, image=weather_icon) # Adjust position as needed
# Display city and weather info using UniHiker's default font
info_city = screen.draw_text(x=0, y=100, text='City: '+city, color='#000000')
info_weather = screen.draw_text(x=0, y=120, text='Weather: '+weather, color='#000000')
info_temp = screen.draw_text(x=0, y=140, text=f'Temp: {temperature}°C', color='#000000')
info_humidity = screen.draw_text(x=0, y=160, text=f'Humidity: {humidity}%', color='#000000')
info_wind = screen.draw_text(x=0, y=180, text=f'Wind Speed: {wind_speed} m/s', color='#000000')
# Main function to run the weather station
def main():
"""
Main function that sets up variables and retrieves and displays weather data on the UniHiker.
"""
# User-defined variables (replace with actual credentials)
api_key = '++++++++++change_me+++++++++++' # OpenWeatherMap API key
city = 'Zagreb' # City name
lat = '45.815399' # Latitude of the city (Zagreb)
lon = '15.966568' # Longitude of the city (Zagreb)
while True: # Infinite loop to keep fetching data
# Get weather data from OpenWeatherMap
weather_data = get_weather(api_key, lat, lon)
# Display weather on the screen
display_weather(weather_data, city)
# Wait for 10 minutes before fetching new data
time.sleep(600) # Sleep for 600 seconds (10 minutes)
# Run the main function to start the weather station
main()
Find variable “api_key” inside code and replace it with your own API key
# User-defined variables (replace with actual credentials)
api_key = '++++++++++change_me+++++++++++' # OpenWeatherMap API key
Find variables city, lat and lon and change them to match your local city or city that you want to monitor.
city = 'Zagreb' # City name
lat = '45.815399' # Latitude of the city (Zagreb)
lon = '15.966568' # Longitude of the city (Zagreb)
Code Breakdown:
get_weather(api_key, lat, lon): Fetches weather data from the OpenWeatherMap API using the given latitude and longitude.
get_weather_icon(weather_id): Maps the weather_id (condition code) to the corresponding weather icon PNG file path.
display_weather(data, city): Extracts and displays the city name, weather description, temperature, humidity, wind speed, and the corresponding weather icon on the UniHiker screen.
Main Loop: The weather data is fetched and displayed every 10 minutes using the time.sleep() function in the main loop to keep the display updated.
Example of Displayed Information:
For a city like Zagreb, the screen will show the following details:
City: Zagreb
Weather: Clear sky
Temp: 23°C
Humidity: 60%
Wind Speed: 3.5 m/s
Weather Icon: A sun icon representing clear weather.
Practical Applications:
This project is perfect for:
Learning IoT: Combining sensors, data fetching from external APIs, and displaying information on a microcontroller.
Weather Monitoring: Placing this weather station at home or in the office to keep track of real-time weather conditions.
Education: A hands-on project for students to understand APIs, microcontrollers, and basic weather concepts.