#!/usr/bin/python3 ''' Weather acquirer for: https://github.com/miklhh/i3blocks-config ''' import os import datetime import xml.etree.ElementTree as ET import requests # Forecast URL. #YR_URL = "https://www.yr.no/place/Sverige/%C3%96sterg%C3%B6tland/Link%C3%B6ping/forecast.xml" #YR_URL = "https://www.yr.no/place/Spain/Valencia/Valencia/forecast.xml" YR_URL = "https://www.yr.no/place/Spain/Valencia/X%C3%A0tiva/forecast.xml" # Good to have data + funky emojicons. FORECAST_CACHE_FILE = os.path.dirname(os.path.realpath(__file__)) + "/forecast.xml" # Emojis associatted with weather # Day # Night WEATHER_TYPES = { "Fair" : ["☀️", "🌙"], #pylint: disable=C0326 "Partly cloudy" : ["⛅", "☁️"], #pylint: disable=C0326 "Clear sky" : ["☀️", "🌙"], #pylint: disable=C0326 "Cloudy" : ["☁️", "☁️"], #pylint: disable=C0326 "Light rain" : ["🌧️", "🌧️"], #pylint: disable=C0326 "Rain" : ["🌧️", "🌧️"], #pylint: disable=C0326 "Heavy Rain" : ["🌧️", "🌧️"], #pylint: disable=C0326 "Light snow" : ["🌨️", "🌨️"], #pylint: disable=C0326 "Snow" : ["🌨️", "🌨️"], #pylint: disable=C0326 "Heavy snow" : ["🌨️", "🌨️"], #pylint: disable=C0326 "Foggy" : ["🌫️", "🌫️"], #pylint: disable=C0326 "Fog" : ["🌫️", "🌫️"], #pylint: disable=C0326 "Light snow showers" : ["🌨️", "🌨️"]} #pylint: disable=C0326 def get_xml_root(): """ Returns a weather XML root, cached from old data if necessary. """ yr_response = 0 try: # Request data from YR. yr_response = requests.get(YR_URL) if yr_response.status_code != 200: raise RuntimeError('Error: YR status code ' + str(yr_response.status_code)) # New response, store in cache file and return XML root. with open(FORECAST_CACHE_FILE, "w") as file_handle: file_handle.write(yr_response.text) return ET.fromstring(yr_response.text) except requests.ConnectionError: # Probably just no internet. Use cached forecast. if os.path.isfile(FORECAST_CACHE_FILE): with open(FORECAST_CACHE_FILE) as file_handle: yr_response = file_handle.read() # Print recycle emoji and continue using cached forecast. print("(♻️)", end=" ") return ET.fromstring(yr_response) # Dead end, no XML-root acquired. raise RuntimeError('No forecast data available.') def main(): """ Entry point for program. """ # Get the XML root. try: xml_root = get_xml_root() except RuntimeError as exception: print(exception) # Parse the sun rise and set time. Appearntly, they are not always available and # so we need to make sure they exist in the recieved data. rise_fall_available = True sun_rise_time = sun_set_time = "" try: sun_rise_time = xml_root.find("sun").attrib.get("rise") sun_rise_time = sun_rise_time[sun_rise_time.find('T')+1 : len(sun_rise_time)-3] sun_set_time = xml_root.find("sun").attrib.get("set") sun_set_time = sun_set_time[sun_set_time.find('T')+1 : len(sun_set_time)-3] except (ET.ParseError, AttributeError): rise_fall_available = False # Get the current weather information. forecast = xml_root.find("forecast").find("tabular").find("time") weather = forecast.find("symbol").attrib.get("name") temperature = forecast.find("temperature").attrib.get("value") wind_direction = forecast.find("windDirection").attrib.get("code") wind_speed = forecast.find("windSpeed").attrib.get("mps") precipitation = forecast.find("precipitation").attrib.get("value") # Night time? is_night = 0 now = datetime.datetime.now() if rise_fall_available: # Use sun rise and fall time to determine. sun_rise = datetime.datetime.strptime(sun_rise_time, "%H:%M") sun_set = datetime.datetime.strptime(sun_set_time, "%H:%M") is_night = 1 if now.time() < sun_rise.time() or sun_set.time() < now.time() else 0 else: # No rise/fall time available. Approximate daytime as [07:00 - 21:00]. sun_rise = datetime.datetime.strptime("07:00", "%H:%M") sun_set = datetime.datetime.strptime("21:00", "%H:%M") is_night = 1 if now.time() < sun_rise.time() or sun_set.time() < now.time() else 0 # Print the weather. if weather in WEATHER_TYPES: # Emoji is avaiable for usage. print(weather + ": " + WEATHER_TYPES.get(weather)[is_night] + " ", end="") else: # No emoji available, use regular text. print(weather + " ", end="") # Print the temperature and sun times. print(temperature, end="°C ") # Print the sun rise and set time. if rise_fall_available: #print("[" + sun_rise_time + " 🌅 " + sun_set_time + "]", end=" ") print("[""WE""]", end=" ") # Print the precipitation (if there is any). if precipitation != "0": # Print with a wet umbrella print("| ☔ " + precipitation + "mm", end=" ") # Print wind data. print("| 🍃 " + wind_speed + "m/s " + "(" + wind_direction + ")", end="") # Go gadget, go! main()