#!/usr/bin/env python3 """ Nicht-interaktive Registrierung eines neuen Homematic-IP-Clients (analog zu homematicip.cli.hmip_generate_auth_token, aber ohne input()-Prompts, damit die Node-API sie als Hintergrundprozess starten und den Fortschritt pollen kann). Usage: python3 hmip_register.py Schreibt fortlaufend JSON-Status nach STATUS_FILE: {"state": "waiting_for_button"} {"state": "success", "authToken": "...", "accessPoint": "...", "clientId": "..."} {"state": "error", "message": "..."} """ import asyncio import json import sys import homematicip.auth from homematicip.connection.connection_context import ConnectionContextBuilder from homematicip.connection.rest_connection import RestConnection def write_status(path, data): with open(path, "w") as f: json.dump(data, f) async def main(): if len(sys.argv) != 3: print("Usage: hmip_register.py ", file=sys.stderr) sys.exit(1) access_point = sys.argv[1].replace("-", "").upper() status_file = sys.argv[2] if len(access_point) != 24: write_status(status_file, {"state": "error", "message": "Ungültige SGTIN (erwartet 24 Zeichen ohne Bindestriche)"}) sys.exit(1) try: context = await ConnectionContextBuilder.build_context_async(access_point) connection = RestConnection(context, log_status_exceptions=False) auth = homematicip.auth.Auth(connection, context.client_auth_token, access_point) response = await auth.connection_request(access_point, "wg-verwaltung") if response.status != 200: body = json.loads(response.text) write_status(status_file, {"state": "error", "message": body.get("errorCode", "Unbekannter Fehler")}) sys.exit(1) write_status(status_file, {"state": "waiting_for_button"}) attempts = 0 while not await auth.is_request_acknowledged(): attempts += 1 if attempts > 180: # 180 * 2s = 6 Minuten Timeout write_status(status_file, {"state": "error", "message": "Zeitüberschreitung: Knopf am Access Point wurde nicht rechtzeitig gedrückt"}) sys.exit(1) await asyncio.sleep(2) auth_token = await auth.request_auth_token() client_id = await auth.confirm_auth_token(auth_token) write_status(status_file, { "state": "success", "authToken": auth_token, "accessPoint": access_point, "clientId": client_id, }) except Exception as e: write_status(status_file, {"state": "error", "message": str(e)}) sys.exit(1) if __name__ == "__main__": asyncio.run(main())