145 lines
5.2 KiB
Python
Executable File
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()
|