#!/usr/bin/env python3 """ BLE Reset/Clear for WellNuo WP sensors Try to clear stuck WiFi state """ import asyncio from bleak import BleakClient, BleakScanner # Sensor BLE UUIDs SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b" CHAR_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8" DEVICE_PIN = "7856" response_data = None response_event = asyncio.Event() def notification_handler(sender, data): global response_data decoded = data.decode('utf-8', errors='replace') print(f" [NOTIFY] {decoded}") response_data = decoded response_event.set() async def send_and_wait(client, command, timeout=10): global response_data response_data = None response_event.clear() print(f"\n>>> Sending: {command}") await client.write_gatt_char(CHAR_UUID, command.encode('utf-8')) try: await asyncio.wait_for(response_event.wait(), timeout=timeout) return response_data except asyncio.TimeoutError: try: data = await client.read_gatt_char(CHAR_UUID) decoded = data.decode('utf-8', errors='replace') print(f" [READ] {decoded}") return decoded except: print(f" [TIMEOUT]") return None async def main(): print("=" * 60) print("WellNuo Sensor Reset Tool") print("=" * 60) print("\nScanning for sensors...") devices = await BleakScanner.discover(timeout=5.0) wp_device = None for d in devices: if d.name and d.name.startswith("WP_"): wp_device = d print(f" Found: {d.name} ({d.address})") break if not wp_device: print("No WP sensor found!") return print(f"\nConnecting to {wp_device.name}...") async with BleakClient(wp_device.address) as client: print("Connected!") await client.start_notify(CHAR_UUID, notification_handler) # Read initial status print("\n--- Current status ---") data = await client.read_gatt_char(CHAR_UUID) print(f"Status: {data.decode('utf-8', errors='replace')}") # Unlock print("\n--- Unlock ---") await send_and_wait(client, f"pin|{DEVICE_PIN}") # Try various reset commands print("\n--- Trying reset commands ---") commands = [ "W|clear", # Clear WiFi settings "W|reset", # Reset WiFi "reset", # General reset "factory", # Factory reset? "W|", # Empty WiFi command "W|scan", # Alternative scan command ] for cmd in commands: await send_and_wait(client, cmd, timeout=5) await asyncio.sleep(1) # Now try WiFi list again print("\n--- Try WiFi list after reset ---") response = await send_and_wait(client, "W|list", timeout=15) if response: print(f"Response: {response}") if "|W|list|" in response: parts = response.split("|W|list|") if len(parts) > 1: networks = parts[1].split("|") print("\n📶 WiFi networks:") for net in networks: if "," in net: ssid, rssi = net.rsplit(",", 1) print(f" - {ssid} ({rssi})") await client.stop_notify(CHAR_UUID) print("\n" + "=" * 60) if __name__ == "__main__": asyncio.run(main())