diff --git a/config.jsonc b/config.jsonc index 8af693b..ae73bdc 100644 --- a/config.jsonc +++ b/config.jsonc @@ -5,7 +5,7 @@ "exclusive": true, "passthrough": false, "gtk-layer-shell": true, - "height": 18, + "height": 45, "modules-left": ["clock","custom/weather","custom/wallpaper","hyprland/window"], "modules-center": ["hyprland/workspaces"], "modules-right": ["network", "bluetooth", "temperature","custom/power_profile","battery","backlight","pulseaudio","pulseaudio#microphone","tray","idle_inhibitor"], @@ -43,10 +43,10 @@ "custom/power_profile": { - "exec": "powerprofilesctl get", + "exec": "powerprofilesctl get || echo 'Unknown'", "interval": 5, "format": "󰈐 {}", - "on-click": "pp=$(powerprofilesctl get); case \"$pp\" in performance) n=balanced;; balanced) n=powersave;; *) n=performance;; esac; powerprofilesctl set \"$n\"; pkill -SIGRTMIN+8 waybar", + "on-click": "pp=$(powerprofilesctl get 2>/dev/null || echo 'balanced'); case \"$pp\" in performance) n=balanced;; balanced) n=powersave;; *) n=performance;; esac; powerprofilesctl set \"$n\" 2>/dev/null || echo 'powerprofilesctl not available'; pkill -SIGRTMIN+8 waybar", "signal": 8, "return-type": "string" }, diff --git a/scripts/waybar-wttr.py b/scripts/waybar-wttr.py index 52a3199..1febe03 100755 --- a/scripts/waybar-wttr.py +++ b/scripts/waybar-wttr.py @@ -2,118 +2,161 @@ import json import requests +import sys from datetime import datetime -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': '❄️ ' +# Default fallback data +data = { + "text": "Weather N/A", + "tooltip": "Weather data unavailable" } -data = {} - - -weather = requests.get("https://wttr.in/?format=j1").json() - - -#Def format_time(time): -# return time.replace("00", "").zfill(2) - - -def format_temp(temp): - return (hour['FeelsLikeF']+"°").ljust(3) - - -def format_chances(hour): - chances = { - "chanceoffog": "Fog", - "chanceoffrost": "Frost", - "chanceofovercast": "Overcast", - "chanceofrain": "Rain", - "chanceofsnow": "Snow", - "chanceofsunshine": "Sunshine", - "chanceofthunder": "Thunder", - "chanceofwindy": "Wind" +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': '❄️ ' } - conditions = [] - for event in chances.keys(): - if int(hour[event]) > 0: - conditions.append(chances[event]+" "+hour[event]+"%") - return ", ".join(conditions) + def format_time(time): + return time.replace("00", "").zfill(2) -tempint = int(weather['current_condition'][0]['FeelsLikeF']) -#extrachar = '' -if tempint > 0 and tempint < 10: - extrachar = '+' + 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" + } -data['text'] = ' '+WEATHER_CODES[weather['current_condition'][0]['weatherCode']] + \ - " "+extrachar+weather['current_condition'][0]['FeelsLikeF']+"°" + conditions = [] + for event in chances.keys(): + if int(hour.get(event, 0)) > 0: + conditions.append(chances[event]+" "+hour.get(event, "")+"%") + return ", ".join(conditions) -data['tooltip'] = f"{weather['current_condition'][0]['weatherDesc'][0]['value']} {weather['current_condition'][0]['temp_F']}°\n" -data['tooltip'] += f"Feels like: {weather['current_condition'][0]['FeelsLikeF']}°\n" -data['tooltip'] += f"Wind: {weather['current_condition'][0]['windspeedKmph']}Km/h\n" -data['tooltip'] += f"Humidity: {weather['current_condition'][0]['humidity']}%\n" -for i, day in enumerate(weather['weather']): - data['tooltip'] += f"\n" - if i == 0: - data['tooltip'] += "Today, " - if i == 1: - data['tooltip'] += "Tomorrow, " - data['tooltip'] += f"{day['date']}\n" - data['tooltip'] += f"⬆️ {day['maxtempF']}° ⬇️ {day['mintempF']}° " - data['tooltip'] += f"🌅 {day['astronomy'][0]['sunrise']} 🌇 {day['astronomy'][0]['sunset']}\n" - for hour in day['hourly']: - if i == 0: - if int(format_time(hour['time'])) < datetime.now().hour-2: - continue - data['tooltip'] += f"{format_time(hour['time'])} {WEATHER_CODES[hour['weatherCode']]} {format_temp(hour['FeelsLikeF'])} {hour['weatherDesc'][0]['value']}, {format_chances(hour)}\n" + # 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"{current.get('weatherDesc', [{'value': 'Unknown'}])[0].get('value', 'Unknown')} {current.get('temp_F', '0')}°\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" + if i == 0: + data['tooltip'] += "Today, " + elif i == 1: + data['tooltip'] += "Tomorrow, " + data['tooltip'] += f"{day.get('date', '')}\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)) diff --git a/style.css b/style.css index eb8f06f..02e3698 100644 --- a/style.css +++ b/style.css @@ -8,7 +8,6 @@ font-family: "JetBrainsMono Nerd Font"; font-weight: bold; font-size: 14px; - line-height: 16px; min-height: 0; } @@ -20,7 +19,7 @@ window#waybar { #workspaces button { - padding: 2px 6px; + padding: 5px; color: @color4; margin-right: 5px; } @@ -45,6 +44,7 @@ window#waybar { background: @background; color: @color12; border-radius: 10px; + font-size: 18px; } #custom-power_profile, @@ -63,8 +63,9 @@ window#waybar { background: @background; color: @color12; opacity: 0.8; - padding: 0px 6px; - margin: 1px 0px; + padding: 0px 10px; + margin: 3px 0px; + margin-top: 10px; border: 1px solid #181825; }