From 05da0e10926d4ade3b10a55999a0ed1b797caf65 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Wed, 14 May 2025 22:50:39 +0530 Subject: added luastatus config --- .config/luastatus-scripts-dwm/bluetooth.lua | 177 ++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 .config/luastatus-scripts-dwm/bluetooth.lua (limited to '.config/luastatus-scripts-dwm/bluetooth.lua') diff --git a/.config/luastatus-scripts-dwm/bluetooth.lua b/.config/luastatus-scripts-dwm/bluetooth.lua new file mode 100644 index 0000000..f4807a0 --- /dev/null +++ b/.config/luastatus-scripts-dwm/bluetooth.lua @@ -0,0 +1,177 @@ +-- A widget to display currently connected and paired bluetooth devices. +-- To change output format modify reprint_devices function. + +separator = " " + +-- Object paths look like /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/somethingsomething +function get_device_mac_address(device_object_path) + return device_object_path:gsub("/.*/dev_", ""):gsub("/.*", ""):gsub("_", ":") +end + +-- For reference bluetoothctl devices output looks like that: +-- Device XX:XX:XX:XX:XX:XX JBL T450BT +-- Device YY:YY:YY:YY:YY:YY Redmi 8 +-- +-- Function returns mac addresses of all devices. +function get_devices() + local devices = {} + local handle = io.popen(string.format("bluetoothctl devices")) + for line in handle:lines() do + table.insert(devices, string.match(line, "Device ([%x:]+)")) + end + handle:close() + return devices +end + +function get_power_state() + local handle = io.popen(string.format("bluetoothctl show")) + local power_state = false + for line in handle:lines() do + local state = string.match(line, "^%s*PowerState:%s*(%w+)") + if state then + if state == "off" then + power_state = false + else + power_state = true + end + break + end + end + handle:close() + + return power_state +end + +-- For reference bluetoothctl info output looks like that: +-- Device XX:XX:XX:XX:XX:XX (public) +-- Name: JBL T450BT +-- Alias: JBL T450BT +-- Class: 0xFFFFFFFF +-- Icon: audio-card +-- Paired: yes +-- Trusted: yes +-- Blocked: no +-- Connected: yes +-- LegacyPairing: no +-- UUID: Headset (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) +-- ... +-- UUID: Handsfree (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) +-- +-- Given this input function returns a following table: +-- [alias] string JBL T450BT +-- [blocked] boolean false +-- [class] string 0x00240404 +-- [connected] boolean true +-- [icon] string audio +-- [legacypairing] boolean false +-- [name] string JBL T450BT +-- [paired] boolean true +-- [trusted] boolean true +function get_device_info(mac_address) + if mac_address == nil then + mac_address = "" + end + local device_info = {} + local handle = io.popen(string.format("bluetoothctl info %s", mac_address)) + for line in handle:lines() do + local key, value = string.match(line, "(%w+): (.*)") + -- Filter junk + if key ~= "UUID" and key ~= nil and value ~= nil then + key = string.lower(key) + if key ~= "name" and key ~= "alias" and key ~= "icon" then + if value == "yes" then + value = true + end + if value == "no" then + value = false + end + end + device_info[key] = value + end + end + handle:close() + return device_info +end + +devices = {} + +function reprint_devices(power_state) + if power_state then + local t = {} + for mac_address, device in pairs(devices) do + table.insert(t, string.format("󰂱 %s", device["alias"])) + end + if next(t) == nil then + return "󰂯" + else + return table.concat(t, separator) + end + else + return "󰂲" + end +end + +widget = { + plugin = "dbus", + opts = { + greet = true, + -- https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt + signals = { + { + sender = "org.bluez", + interface = "org.freedesktop.DBus.Properties", + signal = "PropertiesChanged", + arg0 = "org.bluez.Device1", + bus = "system" + }, { + sender = "org.bluez", + interface = "org.freedesktop.DBus.Properties", + signal = "PropertiesChanged", + arg0 = "org.bluez.Adapter1", + bus = "system" + } + } + }, + cb = function(t) + local power_state = false + if t.what == "hello" then + power_state = get_power_state() + local mac_addresses = get_devices() + for i, mac_address in pairs(mac_addresses) do + local device = get_device_info(mac_address) + if device["connected"] and device["paired"] then + devices[mac_address] = device + end + end + elseif t.what == "signal" then + -- For reference message from dbus looks like that: + -- table + -- [1] string org.bluez.Device1 + -- [2] table + -- [2] [1] table + -- [2] [1] [1] string SomethingSomething + -- [2] [1] [2] boolean false + -- [2] [2] table + -- [2] [2] [1] string Connected + -- [2] [2] [2] boolean true + -- [3] table + if t.signal == "PropertiesChanged" then + power_state = get_power_state() + for i, message in pairs(t.parameters[2]) do + if message[1] == "Connected" or message[1] == "Paired" then + local mac_address = get_device_mac_address(t.object_path) + if message[2] then + local device = get_device_info(mac_address) + if device["paired"] then + devices[mac_address] = device + end + else + devices[mac_address] = nil + end + end + end + end + end + return reprint_devices(power_state) + end +} -- cgit v1.2.3