#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json from typing import Union from ..HueGroup import HueGroup from ..HueLight import HueLight from ..HueUtils import make_request class HueBridge: """This class represents a Hue Bridge """ def __init__(self, ipaddress: str, username: str, name: str = ""): """ Constructor Args: ipaddress (str): The ip address of the bridge username (str): The username for this app for this bridge name (str, optional): A human readable name for this bridge. Is set to ipaddress, if not supplied. """ self.m_ipaddress: str = ipaddress self.m_username: str = username if name: self.m_name: str = name else: self.m_name = self.m_ipaddress self.m_lights: list[HueLight] = self.discover_lights() self.m_groups: list[HueGroup] = self.discover_groups() def __str__(self) -> str: """The string representation of this bridge Returns: str: Returns the name """ return self.m_name def append_new_lights(self) -> bool: """If any new lights were discovered in discover_new_lights(), they can be appended to this bridges list of lights with this function Returns: bool: True if the request was ok, otherwise False """ path: str = "{}/lights/new".format(self.m_username) response = make_request(self.m_ipaddress, path) for key, value in json.loads(response.text).items(): if key != 'lastscan': path: str = "{}/lights/{}".format(self.m_username, key) response = make_request(self.m_ipaddress, path) self.m_lights.append(HueLight(int(key), response.json(), self.get_ipaddress(), self.get_user())) return response.ok def create_group(self, lights: list[HueLight], name: str, group_type: str = "LightGroup", group_class: str = "Other") -> bool: """Create a group from a list of lights Args: lights (list[HueLight]): a list of lights to group name (str): The name of the new group group_type (str, optional): The group type can be “LightGroup”, “Room” or either “Luminaire” or “LightSource” if a Multisource Luminaire is present in the system. Defaults to "LightGroup". group_class (str, optional): Category of Room Types. Defaults to "Other". Returns: bool: True if creation was a success, otherwise False """ path = "{}/groups".format(self.get_user()) method = "POST" data: dict = {'lights': [], 'name': name, 'type': group_type, 'class': group_class} for light in lights: data['lights'].append(str(light.get_id())) response = make_request(self.get_ipaddress(), path, method, json.dumps(data)) r_json = response.json() if 'success' in r_json.keys(): new_id = r_json['success']['id'] new_path = "{}/groups/{}".format(self.get_user(), new_id) new_group = make_request(self.get_ipaddress(), new_path).json() self.m_groups.append(HueGroup(int(new_id), lights, new_group, self.get_ipaddress(), self.get_user())) return True else: return False def discover_groups(self) -> list[HueGroup]: """Get groups from Hue Api Returns: list[HueGroup]: discovered groups """ path: str = "{}/groups".format(self.m_username) response = make_request(self.m_ipaddress, path) groups: list[HueGroup] = list() for key, value in json.loads(response.text).items(): lights: list[HueLight] = list() for light in value['lights']: lights.append(self.get_light_by_id(int(light))) groups.append(HueGroup(int(key), lights, value, self.get_ipaddress(), self.get_user())) return groups def discover_lights(self) -> list[HueLight]: """Get lights from Hue API Returns: list[HueLight]: List of discovered lights """ path: str = "{}/lights".format(self.m_username) response = make_request(self.m_ipaddress, path) lights: list[HueLight] = list() for key, value in json.loads(response.text).items(): lights.append(HueLight(int(key), value, self.get_ipaddress(), self.get_user())) return lights def discover_new_lights(self, light_ids: Union[None, list[int]] = None) -> bool: """Makes bridge search for new lights Args: light_ids (Union[None, list[int]], optional): Either a list of light ids or None. Defaults to None. Returns: bool: True if bridge has started looking for new lights, otherwise False """ body: str = "" if light_ids is not None: body_dict = {'deviceid': []} for device in light_ids: body_dict['deviceid'].append(device) body = json.dumps(body_dict) path: str = "{}/lights".format(self.m_username) method: str = "POST" response = make_request(self.m_ipaddress, path, method, body) return 'success' in response.json()[0].keys() def get_group_by_id(self, group_id: int) -> HueGroup: """Get a specific group Args: group_id (int): The group id of the group to get Returns: HueGroup: The group """ for group in self.m_groups: if group.get_id() == group_id: return group def get_groups(self) -> list[HueGroup]: """Return all the groups of this bridge Returns: list[HueGroup]: A list of all groups owned by this bridge """ return self.m_groups def get_ipaddress(self) -> str: """Get the ip address of this bridge Returns: str: The ip address """ return self.m_ipaddress def get_light_by_id(self, light_id: int) -> HueLight: """Get a specific light Args: light_id (int): The light id of the light to get Returns: HueLight: The light """ for light in self.m_lights: if light.get_id() == light_id: return light def get_lights(self) -> list[HueLight]: """Get all the lights owned by this bridge Returns: list[HueLight]: A flat list of all lights owned by this bridge """ return self.m_lights def get_user(self) -> str: """A user, or username, is more like a password and is needed to authenticate with the Hue API Returns: str: The username """ return self.m_username def remove_light(self, light: HueLight): """Remove a light from all groups and self Args: light (HueLight): The light to remove """ for group in self.m_groups: group.remove_light(light) self.m_lights.remove(light)