import asyncio import json from bleak import BleakClient, BleakScanner DEVICE_NAME = "Bonrix-DQR-222" WRITE_UUID = "87654321-4321-4321-4321-cba987654321" NOTIFY_UUID = "98765432-1234-1234-1234-123456789abc" # Map keys to commands commands = { '1': "WelcomeScreen**7418529631@icici\n", '2': "DisplayFailQRCodeScreen**1234567890ORD10594565**29-03-2023\n", '3': "DisplaySuccessQRCodeScreen**1234567890ORD10594565**29-03-2023\n", '4': "DisplayCancelQRCodeScreen**1234567890ORD10594565**29-03-2023\n", '5': "DisplayQRCodeScreen**upi://pay?pa=63270083167.payswiff@indus&pn=Bonrix&cu=INR&am=10&pn=Bonrix%20Software%20Systems**10**7418529631@icici\n", } json_buffer = "" receiving = False end_marker = None def handle_notification(sender, data): global json_buffer, receiving, end_marker try: msg = data.decode('utf-8', errors='ignore').strip() print(f"šŸ”” BLE Notify: {msg}") if end_marker and msg == end_marker: receiving = False print("\nāœ… End marker received. Transfer complete.") try: parsed = json.loads(json_buffer) print(json.dumps(parsed, indent=2)) except Exception as e: print("āŒ JSON Decode Error:", e) print("šŸ›‘ Raw JSON:") print(json_buffer) json_buffer = "" elif msg.startswith("{") or receiving: receiving = True json_buffer += msg except Exception as e: print("āŒ Notification Error:", e) async def find_device(): print("šŸ” Scanning for ESP32 BLE device...") devices = await BleakScanner.discover() for d in devices: if d.name and DEVICE_NAME in d.name: print(f"āœ… Found {d.name} [{d.address}]") return d.address print("āŒ ESP32 device not found.") return None async def ble_console(): global end_marker, receiving, json_buffer address = await find_device() if not address: return async with BleakClient(address) as client: print("šŸ”— Connected to ESP32 BLE") await client.start_notify(NOTIFY_UUID, handle_notification) await asyncio.sleep(0.1) print("\nšŸ“” Press keys to send commands:\n") print(" 1: Welcome Screen") print(" 2: Fail QR Screen") print(" 3: Success QR Screen") print(" 4: Cancel QR Screen") print(" 5: QR Pay Screen") print(" x: Disconnect\n") while True: key = input(">>> ").strip() if key.lower() == 'x': print("šŸ”Œ Disconnecting...") break if key not in commands: print("ā— Invalid input. Press 1–5 or 'x' to exit.") continue message = commands[key] end_marker = None # No special end marker for now json_buffer = "" receiving = False print(f"šŸ“¤ Sending (chunked): {message.strip()}") chunk_size = 20 message_bytes = message.encode('utf-8') for i in range(0, len(message_bytes), chunk_size): chunk = message_bytes[i:i+chunk_size] print(f"šŸ“¤ Chunk {i//chunk_size + 1}: {chunk}") await client.write_gatt_char(WRITE_UUID, chunk, response=True) await asyncio.sleep(0.02) # Delay for stability for _ in range(100): await asyncio.sleep(0.02) if not receiving and json_buffer: break await client.stop_notify(NOTIFY_UUID) print("āœ… Disconnected") if __name__ == "__main__": asyncio.run(ble_console())