diff --git a/src/config.yaml b/src/config.yaml index 3e35ba6..4a2c8cc 100644 --- a/src/config.yaml +++ b/src/config.yaml @@ -1,6 +1,6 @@ # Configuration for Yasb (Yet Another Status Bar) # Author: @denBot -# Last updated: 08/11/2021 +# Last updated: 21/08/2023 # General Bar Configuration Notes: # - All bars must be defined in within the `bars` section @@ -96,7 +96,7 @@ bars: widgets: left: ["komorebi_workspaces", "komorebi_active_layout", "active_window"] center: ["clock"] - right: ["explorer_button", "ip_info", "cpu", "memory", "battery"] + right: ["explorer_button", "wifi", "cpu", "memory", "battery"] # widgets: # my-clock-widget: @@ -332,9 +332,9 @@ bars: # ^ The format label for the custom widget. Accepts: string containing {data} format options. Required field. # If the command executed returns a JSON structure, # the JSON object can be used within the format label using the python dictionary string formatting syntax. - # - data = "curl.exe api.openweathermap.org/..." - # - data = {"current": {"temp":287.03, "humidity":92}, ...} - # label_alt: "Temperature: {data[current][humidity]}%" + # - data = "curl.exe wttr.in/..." + # - data = {"current_condition": [{"temp_C":16, "humidity":71}], ...} + # label_alt: "Temperature: {data[current_condition][0][temp_C]}%" # ^ The alternate format label for the clock. Accepts: string containing {data} format options. Required field. # label_max_length: None # ^ The maximum length of the label. Accepts: positive integer @@ -442,6 +442,23 @@ widgets: on_middle: 'toggle_monocle' on_right: 'prev_layout' + wifi: + type: "yasb.wifi.WifiWidget" + options: + label: "{wifi_icon}" + label_alt: "{wifi_icon} {wifi_name}" + update_interval: 5000 + wifi_icons: + - "\udb82\udd2e" # 0% strength (no wifi) + - "\udb82\udd1f" # 1-25% strength + - "\udb82\udd22" # 26-50% strength + - "\udb82\udd25" # 51-75% strength + - "\udb82\udd28" # 76-100% strength. Alternate theming: \uf1eb + callbacks: + on_middle: "do_nothing" + on_right: "exec cmd.exe /c start ms-settings:network" + + # Some custom widgets explorer_button: @@ -474,11 +491,12 @@ widgets: weather: type: "yasb.custom.CustomWidget" options: - label: "\uf0c2 {data[main][temp]}\u00b0c" - label_alt: "\uf0c2 {data[weather][0][description]}" + label: "\uf0c2 {data[current_condition][0][temp_C]}\u00b0c" + label_alt: "\uf0c2 {data[current_condition][0][weatherDesc][0][value]}" class_name: "weather-widget" exec_options: - run_cmd: "curl.exe api.openweathermap.org/data/2.5/weather?q=Glasgow&units=metric&appid={YOUR_API_KEY_HERE}" + run_cmd: "curl.exe wttr.in/Vancouver?format=j1" # run every hour run_interval: 3600000 return_format: "json" + diff --git a/src/core/validation/widgets/yasb/wifi.py b/src/core/validation/widgets/yasb/wifi.py new file mode 100644 index 0000000..fa8c04c --- /dev/null +++ b/src/core/validation/widgets/yasb/wifi.py @@ -0,0 +1,62 @@ +DEFAULTS = { + # 'label': '\uf017 {%H:%M:%S}', + # 'label_alt': '\uf017 {%d-%m-%y %H:%M:%S}', + 'label': "{wifi_icon}", + 'label_alt': "{wifi_icon} {wifi_name}", + 'update_interval': 1000, + 'callbacks': { + 'on_left': 'toggle_label', + 'on_middle': 'do_nothing', + 'on_right': 'do_nothing' + }, + 'wifi_icons': [ + "\udb82\udd2e", # Icon for 0% strength + "\udb82\udd1f", # Icon for 1-25% strength + "\udb82\udd22", # Icon for 26-50% strength + "\udb82\udd25", # Icon for 51-75% strength + "\udb82\udd28" # Icon for 76-100% strength + ] +} + +VALIDATION_SCHEMA = { + 'label': { + 'type': 'string', + 'default': DEFAULTS['label'] + }, + 'label_alt': { + 'type': 'string', + 'default': DEFAULTS['label_alt'] + }, + 'update_interval': { + 'type': 'integer', + 'default': DEFAULTS['update_interval'], + 'min': 0, + 'max': 60000 + }, + 'wifi_icons': { + 'type': 'list', + 'default': DEFAULTS['wifi_icons'], + "schema": { + 'type': 'string', + 'required': False + } + }, + 'callbacks': { + 'type': 'dict', + 'schema': { + 'on_left': { + 'type': 'string', + 'default': DEFAULTS['callbacks']['on_left'], + }, + 'on_middle': { + 'type': 'string', + 'default': DEFAULTS['callbacks']['on_middle'], + }, + 'on_right': { + 'type': 'string', + 'default': DEFAULTS['callbacks']['on_right'], + } + }, + 'default': DEFAULTS['callbacks'] + } +} diff --git a/src/core/widgets/yasb/wifi.py b/src/core/widgets/yasb/wifi.py new file mode 100644 index 0000000..b98a900 --- /dev/null +++ b/src/core/widgets/yasb/wifi.py @@ -0,0 +1,109 @@ +from core.widgets.base import BaseWidget +from core.validation.widgets.yasb.wifi import VALIDATION_SCHEMA +from PyQt6.QtWidgets import QLabel +import os + + +class WifiWidget(BaseWidget): + validation_schema = VALIDATION_SCHEMA + + def __init__( + self, + label: str, + label_alt: str, + update_interval: int, + wifi_icons: list[str], + callbacks: dict[str, str], + ): + super().__init__(update_interval, class_name="wifi-widget") + self._wifi_icons = wifi_icons + + self._show_alt_label = False + self._label_content = label + self._label_alt_content = label_alt + + self._label = QLabel() + self._label_alt = QLabel() + self._label.setProperty("class", "label") + self._label_alt.setProperty("class", "label alt") + self.widget_layout.addWidget(self._label) + self.widget_layout.addWidget(self._label_alt) + + self.register_callback("toggle_label", self._toggle_label) + self.register_callback("update_label", self._update_label) + + self.callback_left = callbacks['on_left'] + self.callback_right = callbacks['on_right'] + self.callback_middle = callbacks['on_middle'] + self.callback_timer = "update_label" + + self._label.show() + self._label_alt.hide() + + self.start_timer() + + def _toggle_label(self): + self._show_alt_label = not self._show_alt_label + + if self._show_alt_label: + self._label.hide() + self._label_alt.show() + else: + self._label.show() + self._label_alt.hide() + + self._update_label() + + def _update_label(self): + wifi_icon, _ = self._get_wifi_icon() + wifi_name = self._get_wifi_name() + + # Determine which label is active + active_label = self._label_alt if self._show_alt_label else self._label + + if self._show_alt_label: + updated_content = f"{wifi_icon} {wifi_name}" + else: + updated_content = f"{wifi_icon}" + + active_label.setText(updated_content) + + def _get_wifi_strength(self): + # Get the wifi strength from the system + result = result = os.popen('netsh wlan show interfaces').read() + + # Return 0 if no wifi interface is found + if "There is no wireless interface on the system." in result: + return 0 + + # Extract signal strength from the result + for line in result.split('\n'): + if "Signal" in line: + strength = line.split(":")[1].strip().split(' ')[0].replace('%', '') + return int(strength) + + return 0 + + def _get_wifi_name(self): + result = result = os.popen('netsh wlan show interfaces').read() + + for line in result.split('\n'): + if "SSID" in line: + return line.split(":")[1].strip() + + return "No WiFi" + + def _get_wifi_icon(self): + # Map strength to its corresponding icon + strength = self._get_wifi_strength() + + if strength == 0: + return self._wifi_icons[0], strength + elif strength <= 25: + return self._wifi_icons[1], strength + elif strength <= 50: + return self._wifi_icons[2], strength + elif strength <= 75: + return self._wifi_icons[3], strength + else: + return self._wifi_icons[4], strength diff --git a/src/styles.css b/src/styles.css index a77ef09..405f8f0 100644 --- a/src/styles.css +++ b/src/styles.css @@ -73,6 +73,7 @@ } .cpu-widget .label, +.wifi-widget .label, .memory-widget .label, .battery-widget .label { padding: 2px 5px; @@ -80,6 +81,10 @@ border-radius: 5px; } +.wifi-widget .label { + background: #b8bb26; +} + .cpu-widget .label { background: #d3869b; }