dotfiles/.local/bin/bluetooth_meny.py
2025-05-28 18:33:04 +02:00

145 lines
5.2 KiB
Python
Executable File

#!/usr/bin/env python3
from gi.repository import AppIndicator3
from gi.repository import Gtk, GLib, GObject
import gi
import subprocess
import threading
import time
gi.require_version('Gtk', '3.0') # Usaremos GTK 3 para mayor compatibilidad
gi.require_version('AppIndicator3', '0.1')
class BluetoothMenu:
def __init__(self):
self.app = 'bluetooth-menu'
self.indicator = AppIndicator3.Indicator.new(
self.app,
"bluetooth-disabled-symbolic", # Icono inicial
AppIndicator3.IndicatorCategory.SYSTEM_SERVICES
)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.menu = Gtk.Menu()
self.build_menu()
self.indicator.set_menu(self.menu)
# Iniciar hilo para actualizar el estado del Bluetooth
self.update_thread = threading.Thread(target=self.update_status)
self.update_thread.daemon = True
self.update_thread.start()
def build_menu(self):
# Botón Encender
item_on = Gtk.MenuItem(label='Encender Bluetooth')
item_on.connect('activate', self.turn_on_bluetooth)
self.menu.append(item_on)
# Botón Apagar
item_off = Gtk.MenuItem(label='Apagar Bluetooth')
item_off.connect('activate', self.turn_off_bluetooth)
self.menu.append(item_off)
# Separador
self.menu.append(Gtk.SeparatorMenuItem())
# Botón Salir
item_quit = Gtk.MenuItem(label='Salir')
item_quit.connect('activate', self.quit)
self.menu.append(item_quit)
self.menu.show_all()
def turn_on_bluetooth(self, _):
subprocess.run(['bluetoothctl', 'power', 'on'])
def turn_off_bluetooth(self, _):
subprocess.run(['bluetoothctl', 'power', 'off'])
def quit(self, _):
Gtk.main_quit()
def update_status(self):
# Bucle para actualizar el estado
while True:
GLib.idle_add(self.check_bluetooth_status)
time.sleep(5) # Actualizar cada 5 segundos
def check_bluetooth_status(self):
# Verificar si el Bluetooth está encendido
power_status = subprocess.getoutput(
'bluetoothctl show | grep "Powered:"')
is_powered = 'yes' in power_status.lower()
if not is_powered:
# Bluetooth apagado
self.indicator.set_icon_full(
"/home/teraflops/Icons/bluetooth-poweredoff.png", "Bluetooth Apagado")
self.indicator.set_label("", self.app)
self.indicator.set_title("Bluetooth Apagado")
else:
# Bluetooth encendido, verificar si hay dispositivos conectados
connected_devices = subprocess.getoutput(
'bluetoothctl devices Connected')
if connected_devices:
# Hay dispositivos conectados
device_info = self.get_connected_device_info()
self.indicator.set_icon_full(
"/home/teraflops/Icons/bluetooth-connected.png", "Bluetooth Conectado")
self.indicator.set_label("", self.app)
self.indicator.set_title(
f"Conectado a {device_info['name']} ({device_info['battery']}%)")
else:
# Bluetooth encendido pero sin dispositivos conectados
self.indicator.set_icon_full(
"/home/teraflops/Icons/bluetooth-poweredon.png", "Bluetooth Encendido")
self.indicator.set_label("", self.app)
self.indicator.set_title("Bluetooth Encendido")
def get_connected_device_info(self):
# Obtener la lista de dispositivos conectados
devices = subprocess.getoutput('bluetoothctl devices Connected')
if devices:
for device_line in devices.strip().split('\n'):
parts = device_line.strip().split(' ', 2)
if len(parts) >= 2:
device_mac = parts[1]
device_name = parts[2] if len(
parts) == 3 else 'Dispositivo Desconocido'
# Obtener nivel de batería si está disponible
battery_level = self.get_battery_level(device_mac)
return {'name': device_name, 'battery': battery_level}
return {'name': 'Desconocido', 'battery': 'N/A'}
def get_battery_level(self, device_mac):
try:
# Ejecutar 'bluetoothctl info <MAC>' y obtener la salida
info_output = subprocess.getoutput(
f'bluetoothctl info {device_mac}')
# Buscar la línea que contiene 'Battery Percentage'
for line in info_output.split('\n'):
if 'Battery Percentage' in line:
# Extraer el porcentaje de batería
battery_line = line.strip()
# Formato esperado: 'Battery Percentage: 0x64 (100)'
battery_percentage = battery_line.split('(')[1].strip(')%')
return battery_percentage
# Si no se encuentra la información de batería
return 'N/A'
except Exception as e:
return 'N/A'
def main():
BluetoothMenu()
GObject.threads_init()
Gtk.main()
if __name__ == "__main__":
main()