La aplicación hace una aproximación sobre la distancia, menos da una piedra…
![](https://www.jesusninoc.com/wp-content/uploads/2024/09/Visualizar-graficamente-la-distancia-a-la-que-se-encuentra-un-dispositivo-BLE-Bluetooth-Low-Energy-800x429.png)
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 87 88 89 90 91 |
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_line(stdscr, distance, line_length=50, scale=10, prev_positions=[]): """Representa visualmente la distancia con una barra de estado con una 'X' que se mueve y cambia de color.""" # Limitar la distancia a una escala máxima scaled_distance = min(int(distance * scale), line_length - 1) # Configurar colores 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 # Crear la línea con la 'X' en la posición calculada line = [' '] * line_length # Rellenar hasta la posición actual con amarillo for i in range(scaled_distance + 1): line[i] = 'X' # Mostrar la nueva posición en rojo if 0 <= scaled_distance < line_length: stdscr.addstr(8, 0, ''.join(line), curses.color_pair(2)) # Amarillo stdscr.addstr(8, scaled_distance, 'X', curses.color_pair(1)) # Rojo else: stdscr.addstr(8, 0, ''.join(line), curses.color_pair(2)) # Amarillo 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 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 target_address = "2342423-24234-24234-3234234-asfsdf" prev_positions = [] max_positions = 10 # Máximo número de posiciones a recordar while True: stdscr.clear() # Limpiar pantalla stdscr.addstr(0, 0, "Escaneando dispositivos...", curses.color_pair(3)) # Escanear dispositivos devices = asyncio.run(scan_for_devices()) # Filtrar el dispositivo con la dirección específica target_device = next((device for device in devices if device.address.upper() == target_address.upper()), None) if target_device is None: stdscr.addstr(2, 0, "No se encontró el dispositivo con la dirección especificada.", curses.color_pair(3)) draw_distance_line(stdscr, 0, prev_positions=prev_positions) else: # Calcular distancia para el dispositivo específico rssi = target_device.rssi distance = calculate_distance(rssi) # Mostrar la tabla de datos en blanco stdscr.addstr(2, 0, f"Nombre: {target_device.name or 'Desconocido'}", curses.color_pair(3)) stdscr.addstr(3, 0, f"Dirección: {target_device.address}", curses.color_pair(3)) stdscr.addstr(4, 0, f"RSSI (dBm): {rssi}", curses.color_pair(3)) stdscr.addstr(5, 0, f"Distancia Estimada (metros): {distance:.2f}", curses.color_pair(3)) # Guardar la nueva posición y actualizar la visualización new_pos = int(distance * 10) if new_pos not in prev_positions: prev_positions.append(new_pos) if len(prev_positions) > max_positions: prev_positions.pop(0) # Mantener el número de posiciones dentro del límite draw_distance_line(stdscr, distance, line_length=50, scale=10, prev_positions=prev_positions) time.sleep(1) # Esperar 1 segundo antes de volver a escanear # Ejecutar el escaneo y obtener detalles con curses curses.wrapper(main) |