- Relay pins: G39→G1, G38→G2 - BUNDLED_FIRMWARE_VERSION → SylDaVersions.SERVER (version.txt) - OTA: explicit CCCD descriptor write for Android 13+ - OTA: start packet retry (previously no retry, blocked by pending CCCD) - OTA: firmware path device-mode-aware (server/client subdirs) - Removed stale root firmware.bin, flashMethodGroup, dialog_overwrite_confirm - PrefsHelper: serverUUID/clientUUID persistence
87 lines
2.3 KiB
Python
87 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
"""BLE client for SylDa_Server — send color commands from laptop."""
|
|
|
|
import asyncio
|
|
import sys
|
|
from bleak import BleakScanner, BleakClient
|
|
|
|
SERVICE_UUID = "0000abcd-0000-1000-8000-00805f9b34fb"
|
|
CHAR_UUID = "0000abce-0000-1000-8000-00805f9b34fb"
|
|
SERVER_NAME = "SylDa_Server"
|
|
|
|
COLORS = {
|
|
"r": ("red", b"\x00"),
|
|
"g": ("green", b"\x01"),
|
|
"y": ("yellow", b"\x02"),
|
|
"o": ("orange", b"\x03"),
|
|
"b": ("blue", b"\x04"),
|
|
}
|
|
|
|
|
|
async def find_server():
|
|
print(f"Scanning for {SERVER_NAME}...")
|
|
device = await BleakScanner.find_device_by_name(SERVER_NAME, timeout=10)
|
|
if not device:
|
|
print("Not found.")
|
|
return None
|
|
print(f"Found: {device.name} ({device.address})")
|
|
return device
|
|
|
|
|
|
async def send_color(client, data):
|
|
await client.write_gatt_char(CHAR_UUID, data, response=True)
|
|
print(f"Sent: {COLORS[[k for k, v in COLORS.items() if v[1] == data][0]][0]}")
|
|
|
|
|
|
def show_menu():
|
|
print("\n┌─────────────────────┐")
|
|
print("│ r = red │")
|
|
print("│ g = green │")
|
|
print("│ y = yellow │")
|
|
print("│ o = orange │")
|
|
print("│ b = blue │")
|
|
print("│ q = quit │")
|
|
print("└─────────────────────┘")
|
|
|
|
|
|
async def connect_handler(client):
|
|
print(f"Connected: {client.is_connected}")
|
|
|
|
|
|
async def disconnect_handler(client):
|
|
print("Disconnected from server.")
|
|
|
|
|
|
async def main():
|
|
device = await find_server()
|
|
if not device:
|
|
return
|
|
|
|
async with BleakClient(
|
|
device,
|
|
disconnected_callback=disconnect_handler,
|
|
timeout=10,
|
|
) as client:
|
|
await connect_handler(client)
|
|
|
|
while True:
|
|
try:
|
|
show_menu()
|
|
cmd = await asyncio.get_event_loop().run_in_executor(
|
|
None, lambda: input("> ").strip().lower()
|
|
)
|
|
except (EOFError, KeyboardInterrupt):
|
|
break
|
|
|
|
if cmd == "q":
|
|
break
|
|
elif cmd in COLORS:
|
|
await send_color(client, COLORS[cmd][1])
|
|
else:
|
|
print(f"Unknown: {cmd}")
|
|
|
|
print("Bye.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|