Improve config flow UX for multi-shade setups

Reuse the home key from already-configured shades so adding subsequent
shades skips the key step. Show human-readable shade names from the hub
in the device picker. Allow selecting multiple shades at once instead of
repeating the flow for each one. Default to hub fetch as the key method.
This commit is contained in:
Richard Mann
2026-04-06 09:07:16 +10:00
parent 04c7036351
commit 31185a4446
9 changed files with 540 additions and 47 deletions

View File

@@ -55,12 +55,13 @@ def get_shade_key(hub: str, ble_name) -> bytes:
raise
result: dict = json.loads(shades_exec_resp.content)
if result.get("err") != 0 or len(result.get("responses", [])) != 1:
raise OSError("Error when attempting GetShadeKey")
response: Final[bytes] = bytes.fromhex(result["responses"][0]["hex"])
responses = result.get("responses", [])
if len(responses) != 1 or "hex" not in responses[0]:
raise OSError(f"Error when attempting GetShadeKey: {result}")
response: Final[bytes] = bytes.fromhex(responses[0]["hex"])
dec_resp: Final[dict[str, Any]] = decode_response(response)
if dec_resp["errorCode"] != 0:
raise ValueError("BLE errorCode is not 0")
raise ValueError(f"BLE errorCode={dec_resp['errorCode']} data={dec_resp['data'].hex()}")
if len(dec_resp["data"]) != 16:
raise ValueError("Expected 16 byte homekey")
return dec_resp["data"]
@@ -79,9 +80,23 @@ def main(hub: str) -> int:
shades = json.loads(shades_resp.content)
print(f"Found {len(shades)} shades, interrogating")
network_key: bytes | None = None
for shade in shades:
name: str = base64.b64decode(shade["name"]).decode("utf-8")
key: bytes = get_shade_key(hub, shade["bleName"])
try:
key: bytes = get_shade_key(hub, shade["bleName"])
network_key = key
except (OSError, ValueError) as ex:
if network_key is not None:
key = network_key
print(f"Shade '{name}':")
print(f"\tBLE name: '{shade['bleName']}'")
print(f"\tHomeKey: {key.hex()} (shade unreachable, using network key)")
else:
print(f"Shade '{name}':")
print(f"\tBLE name: '{shade['bleName']}'")
print(f"\tHomeKey: ERROR - {ex}")
continue
print(f"Shade '{name}':")
print(f"\tBLE name: '{shade['bleName']}'")