#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import os import time import uuid import requests import toml from upnpy import UPnP import tinge def connect(ipaddress: str, appid: uuid.UUID = uuid.uuid4()) -> UserOrError: user_or_error = UserOrError() body: dict = json.loads('{"devicetype":"{}#{}"}'.format("tinge", appid)) path: str = "api" method: str = "POST" response: requests.Response = make_request(ipaddress, path, method, body) data: dict = response.json()[0] if 'error' in data.keys(): user_or_error.set_error(data['error']['type']) elif 'success' in data.keys(): user_or_error.set_user(data['success']['username']) else: user_or_error.set_error(9999) return user_or_error def is_valid_config(filename: str) -> bool: return os.path.exists(filename) and os.path.getsize(filename) > 0 def make_request(ipaddress: str, path: str, method: str = "GET", body: dict = json.loads('{}')) -> requests.Response: rfunct = requests.get url = "http://{}/{}".format(ipaddress, path) if method == "PUT": rfunct = requests.put elif method == "POST": rfunct = requests.post elif method == "DELETE": rfunct = requests.delete response: requests.Response = requests.Response() if body: response = rfunct(url, data=body) else: response = rfunct(url) return response class Tinge: def __init__(self): self.mbridges: list[HueBridge] = list() self.mdiscovered: list[str] = list() def discover_new_bridges(self): upnp: UPnP = UPnP() for device in upnp.discover(): if device.get_friendly_name().startswith("Philips hue") and device.host not in self.mdiscovered: user_or_error: UserOrError = connect(device.host) while user_or_error.is_error(): if user_or_error.get_error_code() == 101: print("Please press the button on your Hue Bridge") time.sleep(5) user_or_error = connect(device.host) bridge: HueBridge = HueBridge(device.host, user_or_error.get_user) self.mbridges.append(bridge) self.mdiscovered.append(device.host) def get_bridges_from_file(self): if is_valid_config(self.config): with open(self.config, 'r') as configfile: mbridges = toml.loads(configfile.read()) for bridge, value in mbridges.items(): print(bridge, value['user']) if bridge not in self.mdiscovered: bridge: HueBridge = HueBridge(bridge, value['user']) bridge.connect() self.mbridges.append(bridge) self.mdiscovered.append(bridge) def write_all_bridges_to_conf(self): with open(self.config, 'w') as configfile: for bridge in self.mbridges: configfile.write('["{}"]\nuser = "{}"\n'.format(bridge.ip, bridge.username))