1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import asyncio from bleak import BleakScanner import curses import time # RSSI de referencia y constante de propagación RSSI_REFERENCE = -59 PROPAGATION_CONSTANT = 2 def calculate_distance(rssi, reference=RSSI_REFERENCE, n=PROPAGATION_CONSTANT): return 10 ** ((reference - rssi) / (10 * n)) def draw_distance_lines(stdscr, devices, line_length=50, scale=10): """Representa visualmente la distancia de todos los dispositivos con una barra de estado.""" curses.start_color() curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) # Rojo curses.init_pair(2, curses.COLOR_YELLOW, curses.COLOR_BLACK) # Amarillo curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLACK) # Blanco stdscr.clear() stdscr.addstr(0, 0, "Dispositivos BLE detectados:", curses.color_pair(3)) start_row = 2 max_lines = curses.LINES - start_row # Evitar sobrepasar el límite de la ventana max_cols = curses.COLS - 1 # Evitar sobrepasar el límite de columnas for i, device in enumerate(devices): if i >= max_lines: break rssi = device.rssi distance = calculate_distance(rssi) scaled_distance = min(int(distance * scale), line_length - 1) # Crear la línea con la 'X' en la posición calculada line = [' '] * line_length # Rellenar hasta la posición actual con amarillo for j in range(scaled_distance): line[j] = 'X' # Crear la información del dispositivo device_info = ( f"{device.name or 'Desconocido'} ({device.address})" f" RSSI: {rssi} dBm" f" Distancia: {distance:.2f} m" ) # Limitar la información a lo que cabe en la pantalla info_length = min(len(device_info), max_cols - line_length) info_to_display = device_info[:info_length] # Mostrar la información del dispositivo y la barra de distancia stdscr.addstr(start_row + i, 0, info_to_display, curses.color_pair(3)) # Blanco stdscr.addstr(start_row + i, len(info_to_display), ''.join(line), curses.color_pair(2)) # Amarillo if 0 <= scaled_distance < line_length: stdscr.addstr(start_row + i, len(info_to_display) + scaled_distance, 'X', curses.color_pair(1)) # Rojo stdscr.refresh() async def scan_for_devices(): devices = await BleakScanner.discover() return devices def main(stdscr): curses.curs_set(0) # Ocultar el cursor stdscr.nodelay(1) # Hacer que getch() sea no bloqueante curses.start_color() # Iniciar la capacidad de color while True: stdscr.clear() # Limpiar pantalla stdscr.addstr(0, 0, "Escaneando dispositivos...", curses.color_pair(3)) # Escanear dispositivos devices = asyncio.run(scan_for_devices()) if not devices: stdscr.addstr(2, 0, "No se encontraron dispositivos BLE.", curses.color_pair(3)) else: # Mostrar la distancia de todos los dispositivos detectados draw_distance_lines(stdscr, devices, line_length=50, scale=10) time.sleep(1) # Esperar 1 segundo antes de volver a escanear # Ejecutar el escaneo y obtener detalles con curses curses.wrapper(main) |