import bluetooth, time

SSID = "AhoySmartHome"
PASSWORD = "106granada"
DTU_ADDR = bytes([0x24, 0x19, 0x72, 0x61, 0x9D, 0x62])

log = []
conn_handle = None
done = False
write_handle = None
step = "idle"

# Known Hoymiles GATT write characteristic handle (from previous research)
# Service: 53300000-0023-4bd4-bbd5-a6920e4c5653
# Write char: 53300001-0023-4bd4-bbd5-a6920e4c5653

def bt_irq(event, data):
    global conn_handle, done, write_handle, step
    if event == 7:  # connected
        conn_handle = data[0]
        step = "connected"
        log.append(f"CONN handle={conn_handle}")
        ble.gattc_discover_services(conn_handle)
    elif event == 8:  # disconnected
        log.append(f"DISC err={data[2]}")
        done = True
    elif event == 9:  # service result
        conn, start, end, uuid = data
        log.append(f"SVC {uuid} {start}-{end}")
    elif event == 10:  # service done
        log.append("SVC_DONE - discovering chars")
        ble.gattc_discover_characteristics(conn_handle, 1, 65535)
    elif event == 11:  # characteristic result
        conn, def_h, val_h, props, uuid = data
        uuid_str = str(uuid)
        log.append(f"CHAR {uuid_str} vh={val_h} props={props}")
        # Look for write char (props & 8 = write)
        if '53300001' in uuid_str or (props & 8 and write_handle is None):
            write_handle = val_h
            log.append(f"WRITE_CHAR found at {val_h}")
    elif event == 12:  # char done
        log.append(f"CHAR_DONE write_handle={write_handle}")
        step = "chars_done"
    elif event == 16:  # write done
        log.append("WRITE_ACK received")
        step = "written"
    elif event == 18:  # MTU exchange
        log.append(f"MTU: {data}")

ble = bluetooth.BLE()
ble.active(True)
ble.irq(bt_irq)

log.append("Connecting to DTU...")
ble.gap_connect(0, DTU_ADDR)

# Wait for connection and char discovery
for _ in range(15):
    if step == "chars_done":
        break
    time.sleep(1)

if write_handle and step == "chars_done":
    log.append(f"Writing WiFi creds to handle {write_handle}")
    ssid_b = SSID.encode()
    pw_b = PASSWORD.encode()
    payload = bytes([0x28, len(ssid_b)]) + ssid_b + bytes([len(pw_b)]) + pw_b
    log.append(f"Payload: {payload.hex()}")
    try:
        ble.gattc_write(conn_handle, write_handle, payload, 1)
        time.sleep(3)
    except Exception as e:
        log.append(f"Write error: {e}")
    # Wait for ack
    for _ in range(5):
        if step == "written":
            break
        time.sleep(1)
    log.append(f"Final step: {step}")
else:
    log.append(f"FAILED: step={step} write_handle={write_handle}")

if conn_handle is not None:
    try: ble.gap_disconnect(conn_handle)
    except: pass

with open("/provision_log.txt","w") as f:
    f.write("\n".join(log))
print("DONE")
