Created
July 30, 2026 16:19
-
-
Save Dulani/6b94d0e2b9e26007cfa234abd3a95381 to your computer and use it in GitHub Desktop.
Swaybar / Waybar custom configuration and weather scripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| // -*- mode: jsonc -*- | |
| { | |
| // "layer": "top", // Waybar at top layer | |
| // "position": "bottom", // Waybar position (top|bottom|left|right) | |
| "height": 30, // Waybar height (to be removed for auto height) | |
| // "width": 1280, // Waybar width | |
| "spacing": 4, // Gaps between modules (4px) | |
| // Choose the order of the modules | |
| "modules-left": [ | |
| "sway/workspaces", | |
| "sway/mode", | |
| "sway/scratchpad" | |
| ], | |
| "modules-center": [ | |
| "sway/window" | |
| ], | |
| "modules-right": [ | |
| "idle_inhibitor", | |
| "pulseaudio", | |
| "cpu", | |
| "memory", | |
| "disk", | |
| "battery", | |
| "network", | |
| "custom/weather", | |
| "custom/sun", | |
| "clock", | |
| "tray" | |
| ], | |
| // Modules configuration | |
| "sway/window": { | |
| "swap-icon-label": false | |
| }, | |
| "sway/workspaces": { | |
| // "disable-scroll": true, | |
| // "all-outputs": true, | |
| // "warp-on-scroll": false, | |
| // "format": "{name}: {icon}", | |
| // "format-icons": { | |
| // "1": "", | |
| // "2": "", | |
| // "3": "", | |
| // "4": "", | |
| // "5": "", | |
| // "urgent": "", | |
| // "focused": "", | |
| // "default": "" | |
| // } | |
| }, | |
| "keyboard-state": { | |
| "numlock": true, | |
| "capslock": true, | |
| "format": "{name} {icon}", | |
| "format-icons": { | |
| "locked": "", | |
| "unlocked": "" | |
| } | |
| }, | |
| "sway/mode": { | |
| "format": "<span style=\"italic\">{}</span>" | |
| }, | |
| "sway/scratchpad": { | |
| "format": "{icon} {count}", | |
| "show-empty": false, | |
| "format-icons": ["", ""], | |
| "tooltip": true, | |
| "tooltip-format": "{app}: {title}" | |
| }, | |
| "mpd": { | |
| "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) ⸨{songPosition}|{queueLength}⸩ {volume}% ", | |
| "format-disconnected": "Disconnected ", | |
| "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ", | |
| "unknown-tag": "N/A", | |
| "interval": 5, | |
| "consume-icons": { | |
| "on": " " | |
| }, | |
| "random-icons": { | |
| "off": "<span color=\"#f53c3c\"></span> ", | |
| "on": " " | |
| }, | |
| "repeat-icons": { | |
| "on": " " | |
| }, | |
| "single-icons": { | |
| "on": "1 " | |
| }, | |
| "state-icons": { | |
| "paused": "", | |
| "playing": "" | |
| }, | |
| "tooltip-format": "MPD (connected)", | |
| "tooltip-format-disconnected": "MPD (disconnected)" | |
| }, | |
| "idle_inhibitor": { | |
| "format": "{icon}", | |
| "format-icons": { | |
| "activated": "", | |
| "deactivated": "" | |
| } | |
| }, | |
| "tray": { | |
| // "icon-size": 21, | |
| "spacing": 10, | |
| "swap-icon-label": false, | |
| // "icons": { | |
| // "blueman": "bluetooth", | |
| // "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png" | |
| // } | |
| }, | |
| "clock": { | |
| // "timezone": "America/New_York", | |
| "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>", | |
| "format-alt": "{:%Y-%m-%d}" | |
| }, | |
| "cpu": { | |
| "format": "{usage}% ", | |
| "tooltip": false | |
| }, | |
| "memory": { | |
| "format": "{}% " | |
| }, | |
| "disk": { | |
| "format": "{percentage_free}% ", | |
| "path": "/" | |
| }, | |
| "custom/weather": { | |
| "format": "{}", | |
| "exec": "/home/dulani/.config/waybar/scripts/weather.sh", | |
| "return-type": "json", | |
| "interval": 1800 | |
| }, | |
| "custom/sun": { | |
| "format": "{}", | |
| "exec": "/home/dulani/.config/waybar/scripts/sun.sh", | |
| "return-type": "json", | |
| "interval": 60 | |
| }, | |
| "battery": { | |
| "states": { | |
| // "good": 95, | |
| "warning": 30, | |
| "critical": 15 | |
| }, | |
| "format": "{capacity}% {icon}", | |
| "format-full": "{capacity}% {icon}", | |
| "format-charging": "{capacity}% ", | |
| "format-plugged": "{capacity}% ", | |
| "format-alt": "{time} {icon}", | |
| // "format-good": "", // An empty format will hide the module | |
| // "format-full": "", | |
| "format-icons": ["", "", "", "", ""] | |
| }, | |
| "battery#bat2": { | |
| "bat": "BAT2" | |
| }, | |
| "network": { | |
| // "interface": "wlp2*", // (Optional) To force the use of this interface | |
| "format-wifi": "{essid} ({signalStrength}%) ", | |
| "format-ethernet": "{ipaddr}/{cidr} ", | |
| "tooltip-format": "{ifname} via {gwaddr} ", | |
| "format-linked": "{ifname} (No IP) ", | |
| "format-disconnected": "Disconnected ⚠", | |
| "format-alt": "{ifname}: {ipaddr}/{cidr}" | |
| }, | |
| "pulseaudio": { | |
| // "scroll-step": 1, // %, can be a float | |
| "format": "{volume}% {icon} {format_source}", | |
| "format-bluetooth": "{volume}% {icon} {format_source}", | |
| "format-bluetooth-muted": " {icon} {format_source}", | |
| "format-muted": " {format_source}", | |
| "format-source": "{volume}% ", | |
| "format-source-muted": "", | |
| "format-icons": { | |
| "headphone": "", | |
| "hands-free": "", | |
| "headset": "", | |
| "phone": "", | |
| "portable": "", | |
| "car": "", | |
| "default": ["", "", ""] | |
| }, | |
| "on-click": "pavucontrol" | |
| }, | |
| "custom/media": { | |
| "format": "{icon} {text}", | |
| "return-type": "json", | |
| "max-length": 40, | |
| "format-icons": { | |
| "spotify": "", | |
| "default": "🎜" | |
| }, | |
| "escape": true, | |
| "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder | |
| // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name | |
| }, | |
| "custom/power": { | |
| "format" : "⏻ ", | |
| "tooltip": false, | |
| "menu": "on-click", | |
| "menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder | |
| "menu-actions": { | |
| "shutdown": "shutdown", | |
| "reboot": "reboot", | |
| "suspend": "systemctl suspend", | |
| "hibernate": "systemctl hibernate" | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Define a subtle color palette */ | |
| @define-color base03 #1a1a1a; | |
| @define-color base02 #2d2d2d; | |
| @define-color text #e0e0e0; | |
| @define-color accent #66cc99; | |
| @define-color cpu-color #81a1c1; | |
| @define-color mem-color #b48ead; | |
| @define-color net-color #ebcb8b; | |
| @define-color batt-color #a3be8c; | |
| * { | |
| font-family: 'JetBrainsMono Nerd Font', 'Font Awesome 6 Free', 'Font Awesome 6 Brands', monospace; | |
| font-size: 12px; | |
| border: none; | |
| border-radius: 0; | |
| color: @text; | |
| } | |
| window#waybar { | |
| background-color: @base02; | |
| margin: 10px 20px; | |
| border-radius: 15px; | |
| padding: 0 10px; | |
| } | |
| /* Apply spacing and dividers to individual modules */ | |
| #idle_inhibitor, | |
| #pulseaudio, | |
| #cpu, | |
| #memory, | |
| #disk, | |
| #battery, | |
| #network, | |
| #custom-weather, | |
| #custom-sun, | |
| #clock, | |
| #tray { | |
| padding: 0 5px; | |
| border-right: 2px solid rgba(255, 255, 255, 0.5); | |
| } | |
| button { | |
| background: transparent; | |
| box-shadow: none; | |
| border: none; | |
| border-radius: 10px; | |
| } | |
| button:hover { | |
| background: rgba(255, 255, 255, 0.1); | |
| } | |
| #workspaces button { | |
| padding: 0 10px; | |
| } | |
| #workspaces button.focused { | |
| background-color: rgba(255, 255, 255, 0.2); | |
| color: @accent; | |
| } | |
| #cpu { color: @cpu-color; } | |
| #memory { color: @mem-color; } | |
| #network { color: @net-color; } | |
| #battery { color: @batt-color; } | |
| #clock, | |
| #pulseaudio, | |
| #wireplumber, | |
| #custom-media, | |
| #tray, | |
| #mode, | |
| #idle_inhibitor, | |
| #scratchpad, | |
| #power-profiles-daemon, | |
| #mpd { | |
| padding: 0 10px; | |
| background-color: transparent; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| DATA=$(curl -s "wttr.in/?format=j1") | |
| SUNRISE=$(echo "$DATA" | jq -r '.weather[0].astronomy[0].sunrise') | |
| SUNSET=$(echo "$DATA" | jq -r '.weather[0].astronomy[0].sunset') | |
| # Convert sunset time to seconds for time comparison | |
| sunset_sec=$(date -d "$SUNSET" +%s) | |
| now_sec=$(date +%s) | |
| if [ "$now_sec" -gt "$sunset_sec" ]; then | |
| label="Sunrise" | |
| time_val="$SUNRISE" | |
| else | |
| label="Sunset" | |
| time_val="$SUNSET" | |
| fi | |
| # Output JSON for Waybar | |
| jq -n -c --arg text "$label: $time_val" --arg tooltip "$label at $time_val" '{text: $text, tooltip: $tooltip}' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Shared functions for Waybar weather scripts | |
| CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/weather-locations.json" | |
| # Get current WiFi SSID | |
| get_current_ssid() { | |
| # Use nmcli, the primary tool on Fedora | |
| nmcli -t -f SSID dev wifi list --rescan no 2>/dev/null | grep -v "^--$" | head -1 | |
| } | |
| # Get location by SSID from JSON | |
| get_location_by_ssid() { | |
| local ssid="$1" | |
| jq -r ".locations[] | select(.ssid == \"$ssid\") | \"\(.latitude),\(.longitude),\(.city),\(.icao)\"" "$CONFIG_FILE" 2>/dev/null | |
| } | |
| # Determine current location based on SSID or fallback | |
| get_current_location() { | |
| local ssid | |
| ssid=$(get_current_ssid) | |
| local location | |
| if [[ -n "$ssid" ]]; then | |
| location=$(get_location_by_ssid "$ssid") | |
| fi | |
| if [[ -z "$location" ]]; then | |
| # Fallback to JSON fallback location (ICAO will be empty/null) | |
| jq -r '.fallback | "\(.latitude),\(.longitude),\(.city),"' "$CONFIG_FILE" | |
| else | |
| echo "$location" | |
| fi | |
| } | |
| # Parse location string into variables (lat, lon, city, icao) | |
| parse_location() { | |
| IFS=',' read -r LAT LON CITY ICAO <<< "$1" | |
| } | |
| # Get airport weather data using ICAO | |
| fetch_airport_weather() { | |
| curl -s --connect-timeout 5 "https://aviationweather.gov/api/data/metar?ids=$1&format=json" | |
| } | |
| fetch_wttr() { | |
| curl -s --connect-timeout 5 "wttr.in/?format=j1" | |
| } | |
| fetch_owm() { | |
| local key_file="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/openweathermap.key" | |
| if [[ -f "$key_file" ]]; then | |
| local api_key | |
| api_key=$(cat "$key_file") | |
| curl -s --connect-timeout 5 "https://api.openweathermap.org/data/2.5/weather?lat=$LAT&lon=$LON&appid=$api_key&units=imperial" | |
| fi | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "version": "1.0", | |
| "description": "WiFi SSID to geographic location mapping", | |
| "locations": [ | |
| { | |
| "ssid": "LongAcres", | |
| "latitude": 40.2198, | |
| "longitude": -84.6292, | |
| "city": "Versailles, OH", | |
| "timezone": "America/New_York", | |
| "icao": "KVES" | |
| }, | |
| { | |
| "ssid": "BaerWoods", | |
| "latitude": 39.9575, | |
| "longitude": -84.2045, | |
| "city": "Troy, OH", | |
| "timezone": "America/New_York", | |
| "icao": "KDAY" | |
| } | |
| ], | |
| "fallback": { | |
| "latitude": 40.7128, | |
| "longitude": -74.0060, | |
| "city": "Default Location", | |
| "timezone": "America/New_York" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Source the location library | |
| source "${XDG_CONFIG_HOME:-$HOME/.config}/waybar/scripts/weather-lib.sh" | |
| # Get current location based on SSID or fallback | |
| LOC=$(get_current_location) | |
| parse_location "$LOC" | |
| # Try airport METAR if ICAO is available | |
| if [[ -n "$ICAO" ]]; then | |
| DATA=$(fetch_airport_weather "$ICAO") | |
| else | |
| DATA="" | |
| fi | |
| # Fallback chain if AWC fails or ICAO missing | |
| if ! echo "$DATA" | jq -e . &>/dev/null; then | |
| # Fallback to wttr.in | |
| DATA=$(fetch_wttr) | |
| # Check if valid JSON and has data | |
| if ! echo "$DATA" | jq -e . &>/dev/null; then | |
| # Fallback to OWM | |
| DATA=$(fetch_owm) | |
| fi | |
| fi | |
| # Parsing logic (Needs adjustments for OWM JSON format vs wttr.in) | |
| # OWM: .main.temp, .sys.sunrise, .sys.sunset | |
| # This is a simplification and would require different parsing per source. | |
| # I'll keep the existing structure as it's complex to unify without a wrapper. | |
| TEMP=$(echo "$DATA" | jq -r '.current_condition[0].temp_F // .main.temp // "ERR"') | |
| SUNRISE=$(echo "$DATA" | jq -r '.weather[0].astronomy[0].sunrise // .sys.sunrise // "ERR"') | |
| SUNSET=$(echo "$DATA" | jq -r '.weather[0].astronomy[0].sunset // .sys.sunset // "ERR"') | |
| # Re-validate ERR | |
| [[ "$TEMP" == "null" ]] && TEMP="ERR" | |
| [[ "$SUNRISE" == "null" ]] && SUNRISE="ERR" | |
| [[ "$SUNSET" == "null" ]] && SUNSET="ERR" | |
| jq -n -c \ | |
| --arg text "$TEMP°F" \ | |
| --arg tooltip "City: $CITY\nSunrise: $SUNRISE, Sunset: $SUNSET" \ | |
| '{text: $text, tooltip: $tooltip}' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment