arch-waybar/scripts/waybar-wttr.py

163 lines
5.4 KiB
Python
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
import json
import requests
import sys
from datetime import datetime
# Default fallback data
data = {
"text": "Weather N/A",
"tooltip": "Weather data unavailable"
}
try:
# Try to get weather data
response = requests.get("https://wttr.in/?format=j1", timeout=10)
response.raise_for_status() # Raise an exception for bad status codes
# Parse JSON data
weather = response.json()
# Define weather codes mapping
WEATHER_CODES = {
'113': '☀️ ',
'116': '',
'119': '☁️ ',
'122': '☁️ ',
'143': '☁️ ',
'176': '🌧️',
'179': '🌧️',
'182': '🌧️',
'185': '🌧️',
'200': '⛈️ ',
'227': '🌨️',
'230': '🌨️',
'248': '☁️ ',
'260': '☁️ ',
'263': '🌧️',
'266': '🌧️',
'281': '🌧️',
'284': '🌧️',
'293': '🌧️',
'296': '🌧️',
'299': '🌧️',
'302': '🌧️',
'305': '🌧️',
'308': '🌧️',
'311': '🌧️',
'314': '🌧️',
'317': '🌧️',
'320': '🌨️',
'323': '🌨️',
'326': '🌨️',
'329': '❄️ ',
'332': '❄️ ',
'335': '❄️ ',
'338': '❄️ ',
'350': '🌧️',
'353': '🌧️',
'356': '🌧️',
'359': '🌧️',
'362': '🌧️',
'365': '🌧️',
'368': '🌧️',
'371': '❄️',
'374': '🌨️',
'377': '🌨️',
'386': '🌨️',
'389': '🌨️',
'392': '🌧️',
'395': '❄️ '
}
def format_time(time):
return time.replace("00", "").zfill(2)
def format_temp(temp):
return (temp+"°").ljust(3)
def format_chances(hour):
chances = {
"chanceoffog": "Fog",
"chanceoffrost": "Frost",
"chanceofovercast": "Overcast",
"chanceofrain": "Rain",
"chanceofsnow": "Snow",
"chanceofsunshine": "Sunshine",
"chanceofthunder": "Thunder",
"chanceofwindy": "Wind"
}
conditions = []
for event in chances.keys():
if int(hour.get(event, 0)) > 0:
conditions.append(chances[event]+" "+hour.get(event, "")+"%")
return ", ".join(conditions)
# Safely extract weather data
if 'current_condition' in weather and len(weather['current_condition']) > 0:
current = weather['current_condition'][0]
# Extract temperature safely
feels_like = current.get('FeelsLikeF', '0')
tempint = int(feels_like) if feels_like.isdigit() else 0
extrachar = '+' if 0 < tempint < 10 else ''
# Build text
weather_code = current.get('weatherCode', '113')
weather_icon = WEATHER_CODES.get(weather_code, '')
data['text'] = '' + weather_icon + " " + extrachar + feels_like + "°"
# Build tooltip
data['tooltip'] = f"<b>{current.get('weatherDesc', [{'value': 'Unknown'}])[0].get('value', 'Unknown')} {current.get('temp_F', '0')}°</b>\n"
data['tooltip'] += f"Feels like: {feels_like}°\n"
data['tooltip'] += f"Wind: {current.get('windspeedKmph', '0')}Km/h\n"
data['tooltip'] += f"Humidity: {current.get('humidity', '0')}%\n"
# Add forecast data if available
if 'weather' in weather:
for i, day in enumerate(weather['weather']):
data['tooltip'] += f"\n<b>"
if i == 0:
data['tooltip'] += "Today, "
elif i == 1:
data['tooltip'] += "Tomorrow, "
data['tooltip'] += f"{day.get('date', '')}</b>\n"
data['tooltip'] += f"⬆️ {day.get('maxtempF', '0')}° ⬇️ {day.get('mintempF', '0')}° "
data['tooltip'] += f"🌅 {day.get('astronomy', [{}])[0].get('sunrise', '')} 🌇 {day.get('astronomy', [{}])[0].get('sunset', '')}\n"
# Hourly forecast
hourly = day.get('hourly', [])
for hour in hourly:
if i == 0:
try:
hour_time = int(format_time(hour.get('time', '0')))
if hour_time < datetime.now().hour - 2:
continue
except ValueError:
continue
data['tooltip'] += f"{format_time(hour.get('time', ''))} {WEATHER_CODES.get(hour.get('weatherCode', ''), '')} {format_temp(hour.get('FeelsLikeF', ''))} {hour.get('weatherDesc', [{'value': ''}])[0].get('value', '')}, {format_chances(hour)}\n"
else:
data['text'] = "Weather N/A"
data['tooltip'] = "Weather data unavailable"
except requests.exceptions.RequestException as e:
# Network error
data['text'] = "Weather N/A"
data['tooltip'] = f"Weather error: Network issue ({str(e)})"
except json.JSONDecodeError as e:
# JSON parsing error
data['text'] = "Weather N/A"
data['tooltip'] = f"Weather error: Invalid data ({str(e)})"
except Exception as e:
# Other errors
data['text'] = "Weather N/A"
data['tooltip'] = f"Weather error: {str(e)}"
# Output the result
print(json.dumps(data))