You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tinge/tinge/__init__.py

90 lines
3.0 KiB

#!/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))