this repo has no description

fix: coerce groups string to list in load_state

+6 -9
-8
src/solux/controller.py
··· 166 transition_seconds: float = 60.0, 167 ) -> None: 168 """apply light state to groups.""" 169 - print(f"DEBUG apply_state: groups={groups!r}, type={type(groups)}") 170 bridge = get_bridge() 171 172 if groups is None: 173 all_groups = bridge.get_group() 174 - print(f"DEBUG all_groups type={type(all_groups)}, value={all_groups!r}") 175 if isinstance(all_groups, list): 176 # hue api returns errors as a list, e.g. [{"error": {"description": "..."}}] 177 errors = [] 178 for item in all_groups: 179 - print(f"DEBUG item={item!r}, type={type(item)}") 180 if isinstance(item, dict) and isinstance(item.get("error"), dict): 181 errors.append(item["error"].get("description", str(item["error"]))) 182 if errors: ··· 189 for gid, info in all_groups.items() 190 if isinstance(info, dict) and info.get("name") not in ("all", "Custom group for $lights") 191 ] 192 - print(f"DEBUG resolved groups={groups!r}") 193 194 - print(f"DEBUG iterating over groups={groups!r}") 195 for group_name in groups: 196 - print(f"DEBUG setting group_name={group_name!r}, type={type(group_name)}") 197 bridge.set_group( 198 group_name, 199 {"on": light_state.on, "bri": light_state.bri, "ct": light_state.ct}, ··· 204 def update(groups: list[str] | None = None) -> None: 205 """main update - checks state, applies lights.""" 206 external = load_state() 207 - print(f"DEBUG update: external.groups={external.groups!r}, type={type(external.groups)}") 208 light_state, description = resolve_state(external) 209 target_groups = external.groups or groups 210 - print(f"DEBUG update: target_groups={target_groups!r}, type={type(target_groups)}") 211 212 print(f"[{description}] bri={light_state.bri}, ct={light_state.ct}, on={light_state.on} | {target_groups}") 213 apply_state(light_state, target_groups)
··· 166 transition_seconds: float = 60.0, 167 ) -> None: 168 """apply light state to groups.""" 169 bridge = get_bridge() 170 171 if groups is None: 172 all_groups = bridge.get_group() 173 if isinstance(all_groups, list): 174 # hue api returns errors as a list, e.g. [{"error": {"description": "..."}}] 175 errors = [] 176 for item in all_groups: 177 if isinstance(item, dict) and isinstance(item.get("error"), dict): 178 errors.append(item["error"].get("description", str(item["error"]))) 179 if errors: ··· 186 for gid, info in all_groups.items() 187 if isinstance(info, dict) and info.get("name") not in ("all", "Custom group for $lights") 188 ] 189 190 for group_name in groups: 191 bridge.set_group( 192 group_name, 193 {"on": light_state.on, "bri": light_state.bri, "ct": light_state.ct}, ··· 198 def update(groups: list[str] | None = None) -> None: 199 """main update - checks state, applies lights.""" 200 external = load_state() 201 light_state, description = resolve_state(external) 202 target_groups = external.groups or groups 203 204 print(f"[{description}] bri={light_state.bri}, ct={light_state.ct}, on={light_state.on} | {target_groups}") 205 apply_state(light_state, target_groups)
+6 -1
src/solux/state.py
··· 66 if datetime.now().astimezone() > expires: 67 return State() # expired - return to auto 68 69 return State( 70 mode=Mode(data.get("mode", "auto")), 71 updated_at=data.get("updated_at", ""), ··· 73 brightness=data.get("brightness"), 74 color_temp=data.get("color_temp"), 75 on=data.get("on"), 76 - groups=data.get("groups"), 77 expires_at=data.get("expires_at"), 78 metadata=data.get("metadata", {}), 79 )
··· 66 if datetime.now().astimezone() > expires: 67 return State() # expired - return to auto 68 69 + # ensure groups is a list, not a string 70 + groups = data.get("groups") 71 + if isinstance(groups, str): 72 + groups = [groups] 73 + 74 return State( 75 mode=Mode(data.get("mode", "auto")), 76 updated_at=data.get("updated_at", ""), ··· 78 brightness=data.get("brightness"), 79 color_temp=data.get("color_temp"), 80 on=data.get("on"), 81 + groups=groups, 82 expires_at=data.get("expires_at"), 83 metadata=data.get("metadata", {}), 84 )