From 450754b39a9582df9fbb906fd3cfed86e12d132d Mon Sep 17 00:00:00 2001 From: ltadeu6 Date: Wed, 1 Apr 2026 09:38:18 -0300 Subject: [PATCH] waybar --- waybar/air_control.py | 107 ++++++++++++++++++++++ waybar/config | 200 ++++++++++++++++++++++++++++++++++++++++++ waybar/dracula.css | 31 +++++++ waybar/launch.sh | 10 +++ waybar/style.css | 135 ++++++++++++++++++++++++++++ 5 files changed, 483 insertions(+) create mode 100755 waybar/air_control.py create mode 100644 waybar/config create mode 100644 waybar/dracula.css create mode 100755 waybar/launch.sh create mode 100644 waybar/style.css diff --git a/waybar/air_control.py b/waybar/air_control.py new file mode 100755 index 0000000..decedc1 --- /dev/null +++ b/waybar/air_control.py @@ -0,0 +1,107 @@ +#!/run/current-system/sw/bin/python3 + +import requests +import sys +import os +import json + +HA_URL = "http://localhost:8123" +ENTITY = "climate.ar" +TOKEN_FILE = os.path.expanduser("~/.config/secrets/ha_token") + +STEP = 1 +MIN_TEMP = 18 +MAX_TEMP = 30 + + +def get_token(): + with open(TOKEN_FILE) as f: + return f.read().strip() + + +HEADERS = {"Authorization": f"Bearer {get_token()}", "Content-Type": "application/json"} + + +def get_state(): + r = requests.get(f"{HA_URL}/api/states/{ENTITY}", headers=HEADERS) + return r.json() + + +def set_temperature(temp): + requests.post( + f"{HA_URL}/api/services/climate/set_temperature", + headers=HEADERS, + json={"entity_id": ENTITY, "temperature": temp}, + ) + + +def set_mode(mode): + requests.post( + f"{HA_URL}/api/services/climate/set_hvac_mode", + headers=HEADERS, + json={"entity_id": ENTITY, "hvac_mode": mode}, + ) + + +def display(): + state = get_state() + mode = state["state"] + attrs = state["attributes"] + + current = attrs["current_temperature"] + target = attrs.get("temperature") + + if mode == "off": + print(json.dumps({"text": f"{current:.0f} - ", "class": "off"})) + return + + if mode == "cool": + icon = "" + css_class = "cool" + elif mode == "heat": + icon = "" + css_class = "heat" + else: + icon = "" + css_class = "other" + + print( + json.dumps( + { + "text": f"{icon} {target:.0f} - ", + "class": css_class, + } + ) + ) + + +def change(delta): + state = get_state() + attrs = state["attributes"] + current_target = attrs["temperature"] + + new_temp = max(MIN_TEMP, min(MAX_TEMP, current_target + delta)) + set_temperature(new_temp) + + +def main(): + if len(sys.argv) == 1: + display() + return + + cmd = sys.argv[1] + + if cmd == "heat": + set_mode("heat") + elif cmd == "cool": + set_mode("cool") + elif cmd == "off": + set_mode("off") + elif cmd == "up": + change(STEP) + elif cmd == "down": + change(-STEP) + + +if __name__ == "__main__": + main() diff --git a/waybar/config b/waybar/config new file mode 100644 index 0000000..794b0d0 --- /dev/null +++ b/waybar/config @@ -0,0 +1,200 @@ +{ + "layer": "top", + "position": "top", + "fixed-center": true, + "height": 48, + "margin-top": 20, + "margin-bottom": 0, + "output": ["DP-5", "DP-3"], + "modules-left": ["hyprland/workspaces", "cava"], + "modules-center": ["custom/ac", "clock"], + "modules-right": [ + "mpris", + "network", + "bluetooth", + "pulseaudio", + "backlight", + "battery", + "custom/poweroff" + ], + "group/power": { + "orientation": "inherit", + "drawer": { + "transition-duration": 500, + "transition-left-to-right": false + }, + "modules": [ + "custom/poweroff", + "custom/restart", + "custom/exit", + "custom/sleep", + "custom/lock" + ] + }, + "custom/poweroff": { + "format": "", + "on-click": "poweroff" + }, + "custom/restart": { + "format": "󰑐", + "on-click": "reboot" + }, + "custom/exit": { + "format": "󰗼", + "on-click": "hyprctl dispatch exit" + }, + "custom/sleep": { + "format": "󰤄", + "on-click": "systemctl suspend" + }, + "custom/lock": { + "format": "", + "on-click": "hyprlock" + }, + "custom/kde": { + "format": "", + "on-click": "hyprlock" + }, + "hyprland/workspaces": { + "all-outputs": false, + "active-only": false, + "persistent-workspaces": { + "DP-3": [1, 2, 3, 4, 5, 6, 7, 8, 9], + "DP-5": [1, 2, 3, 4, 5, 6, 7, 8, 9], + "HDMI-A-1": [10] + }, + "format": "{icon}", + "format-icons": { + "1": "", + "2": "", + "3": "", + "4": "󰯉", + "5": "󰭹", + "6": "", + "7": "", + "8": "", + "9": "", + "10": "" + }, + "on-scroll-up": "hyprctl dispatch workspace e+1", + "on-scroll-down": "hyprctl dispatch workspace e-1" + }, + "clock": { + "format": "{:%d/%m/%Y - %H:%M}", + "tooltip": false, + "locale": "pt_BR.utf8" + }, + "cpu": { + "interval": 5, + "format": "︁ {}%", + "max-length": 10 + }, + "cava": { + "framerate": 60, + "hide_on_silence": true, + "bars": 10, + "source": "auto", + "method": "pipewire", + "stereo": true, + "bar_delimiter": 0, + "monstercat": false, + "waves": true, + "noise_reduction": 0.2, + "sleep_timer": 1, + "input_delay": 0, + "format-icons": ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"], + "actions": { + "on-click-right": "mode" + } + }, + "memory": { + "interval": 15, + "format": "︁ {used:0.1f}G/{total:0.1f}G", + "tooltip": false + }, + "pulseaudio": { + "format": "{icon}", + "format-bluetooth": "{icon}", + "format-muted": "", + "format-icons": { + // "headphone": "", + // "hands-free": "", + // "headset": "󱡒", + // "phone": "", + // "portable": "", + // "car": "", + "default": ["󰕿", "󰖀", "󰖀", "󰕾", "󰕾", "󰕾"] + }, + "scroll-step": 10, + "on-click": "pavucontrol", + "ignored-sinks": ["Easy Effects Sink"], + "tooltip-format": "{icon} {volume}" + }, + "bluetooth": { + "format": "󰂯", + "format-connected": "󰂱", + "format-connected-battery": "󰂱", + "tooltip-format": "{controller_alias}\t{controller_address}\n\n{num_connections} connected", + "tooltip-format-connected": "{device_enumerate}", + "tooltip-format-enumerate-connected": "{device_alias}\t{device_address}", + "tooltip-format-enumerate-connected-battery": "{device_alias}\t{device_address}\t{device_battery_percentage}%", + "on-click": "bluetoothctl disconnect", + "on-click-right": "bluetoothctl connect B6:97:1A:3D:6A:B2" + }, + "backlight": { + "device": "intel_backlight", + "format": "{icon}", + "scroll-step": 5, + "format-icons": ["󰃛", "󰃜", "󰃝", "󰃞", "󰃟", "󰃠"] + }, + "mpris": { + "format": "{player_icon} {dynamic}", + "format-paused": "{status_icon} {dynamic}", + "tooltip-format": "{status_icon} {dynamic}", + "player-icons": { + "default": "", + "mpv": "🎵" + }, + "status-icons": { + "paused": "" + }, + "dynamic-len": 40, + "dynamic-order": ["title", "artist", "album"], + "player": "spotify", + "ignored-players": ["firefox*"], + "on-scroll-up": "playerctl -i firefox volume 0.1+", + "on-scroll-down": "playerctl -i firefox volume 0.1-" + }, + "battery": { + "format": "{icon} ", + "format-icons": ["", "", "", "", ""], + "format-charging": "{icon}", + "format-full": "{icon}", + "interval": 15, + "states": { + "warning": 25, + "critical": 10 + }, + "tooltip": false + }, + "network": { + "format": "{icon}", + "format-alt": "󰲝 ︁ {ipaddr}", + "format-alt-click": "click-left", + "format-wifi": " ", + "format-ethernet": "󰲝", + "format-disconnected": "⚠", + "tooltip": false + }, + "custom/ac": { + "exec": "./air_control.py", + "interval": 1, + "return-type": "json", + "markup": "true", + "on-click-right": "./air_control.py heat", + "on-click": "./air_control.py cool", + "on-click-middle": "./air_control.py off", + "on-scroll-up": "./air_control.py up", + "on-scroll-down": "./air_control.py down" +} +} diff --git a/waybar/dracula.css b/waybar/dracula.css new file mode 100644 index 0000000..f184c93 --- /dev/null +++ b/waybar/dracula.css @@ -0,0 +1,31 @@ +@define-color base #24273a; +@define-color mantle #1e2030; +@define-color crust #181926; + +@define-color text #f2f3f7; +@define-color subtext0 #a5adcb; +@define-color subtext1 #b8c0e0; + +@define-color surface0 #282A36; +@define-color surface1 #494d64; +@define-color surface2 #6272A4; + +@define-color overlay0 #6e738d; +@define-color overlay1 #8087a2; +@define-color overlay2 #939ab7; + +@define-color blue #8aadf4; +@define-color lavender #b7bdf8; +@define-color sapphire #7dc4e4; +@define-color sky #91d7e3; +@define-color teal #8BE9FD; +@define-color green #50fa7E; +@define-color yellow #f1fa8c; +@define-color peach #f5a97f; +@define-color maroon #ee99a0; +@define-color red #ff5555; +@define-color mauve #c6a0f6; +@define-color purple #d6acff; +@define-color pink #f5bde6; +@define-color flamingo #f0c6c6; +@define-color rosewater #f4dbd6; diff --git a/waybar/launch.sh b/waybar/launch.sh new file mode 100755 index 0000000..db07846 --- /dev/null +++ b/waybar/launch.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh + +# Terminate already running bar instances +killall -q waybar + +# Wait until the processes have been shut down +while pgrep -x waybar >/dev/null; do sleep 1; done + +# Launch main +waybar \ No newline at end of file diff --git a/waybar/style.css b/waybar/style.css new file mode 100644 index 0000000..9d3633b --- /dev/null +++ b/waybar/style.css @@ -0,0 +1,135 @@ +@import "./dracula.css"; + +* { + font-family: FreeMono; + font-size: 17px; + font-weight: 600; + border: none; +} + +#waybar { + background: transparent; +} + +#workspaces { + color: @teal; +} + +#workspaces button { + color: @teal; + margin: 0 0.8rem 0 0.4rem; + padding: 0; + /* border-bottom-width: 1px; */ +} +#workspaces button:hover { + box-shadow: none; + text-shadow: none; + background: none; + transition: none; +} + +#workspaces button.empty { + color: @surface2; +} + +#workspaces button.visible { + color: @red; +} + +#custom-lock, +#custom-kde, +#custom-restart, +#custom-exit, +#custom-sleep, +#custom-poweroff, +#mpris, +#battery, +#pulseaudio, +#bluetooth, +#backlight, +#network { + padding: 0 1rem; +} +#mpris { + font-family: "GohuFont 11 Nerd Font Mono"; + font-weight: 700; + letter-spacing: 1.5px; +} + +#cava { + font-family: "GohuFont 11 Nerd Font Mono"; + font-weight: 700; + letter-spacing: 1.5px; + color: @teal; + margin: 0 5px 0 10px; +} + +#custom-sleep, +#battery, +#network { + color: @green; +} + +#custom-exit, +#mpris, +#pulseaudio, +#backlight { + color: @yellow; +} + +#custom-kde, +#custom-lock, +#bluetooth { + color: @teal; +} + +#custom-restart, +#custom-poweroff { + color: @red; +} + +#clock, +#custom-ac { + color: @text; + color: @yellow; + font-family: "GohuFont 11 Nerd Font Mono"; + font-weight: 700; + letter-spacing: 1.5px; +} + +#battery.warning:not(.charging) { + color: @red; +} + +/* .modules-left, */ +/* .modules-center, */ +/* .modules-right { */ +/* border: double 3px transparent; */ +/* border-radius: 10px; */ +/* background-image: */ +/* linear-gradient(rgba(12, 10, 32, 1), rgba(12, 10, 32, 1)), */ +/* linear-gradient( */ +/* to bottom right, */ +/* rgba(254, 4, 117, 0.93), */ +/* rgba(32, 241, 253, 0.93) */ +/* ); */ +/* background-origin: border-box; */ +/* background-clip: padding-box, border-box; */ +/* padding: 0 1rem; */ +/* margin: 0 20px; */ +/* } */ + +.modules-left, +.modules-center, +.modules-right { + border: solid 3px; + border-color: @lavender; + border-radius: 10px; + padding: 0 1rem; + background: @surface0; +} + +.modules-right, +.modules-left { + margin: 0 20px; +}