Random local chages

master
Micke Nordin 2 years ago
parent 6f31dff7e8
commit 2ad64ac934
Signed by: micke
GPG Key ID: 0DA0A7A5708FE257

@ -5,7 +5,7 @@ from typing import Union
import wx import wx
import wx.lib.scrolledpanel as scrolled import wx.lib.scrolledpanel as scrolled
from tinge import Tinge, HueBridge, HueGroup, HueLight, HueUtils, is_bridge from tinge import HueBridge, HueGroup, HueLight, HueUtils, Tinge, is_bridge
class Hui(wx.Frame): class Hui(wx.Frame):
@ -14,7 +14,6 @@ class Hui(wx.Frame):
Args: Args:
wx (Frame): Parent class wx (Frame): Parent class
""" """
def redraw(*args): def redraw(*args):
"""Decorator used for redrawing the widgets in the sizer """Decorator used for redrawing the widgets in the sizer
@ -43,7 +42,8 @@ class Hui(wx.Frame):
self.cur_bridge: Union[None, HueBridge] = None self.cur_bridge: Union[None, HueBridge] = None
self.cur_group: Union[None, HueGroup] = None self.cur_group: Union[None, HueGroup] = None
# create a panel in the frame # create a panel in the frame
self.pnl: scrolled.ScrolledPanel = scrolled.ScrolledPanel(self, -1, style=wx.VSCROLL) self.pnl: scrolled.ScrolledPanel = scrolled.ScrolledPanel(
self, -1, style=wx.VSCROLL)
self.pnl.SetupScrolling() self.pnl.SetupScrolling()
# and create a sizer to manage the layout of child widgets # and create a sizer to manage the layout of child widgets
self.sizer: wx.BoxSizer = wx.BoxSizer(wx.VERTICAL) self.sizer: wx.BoxSizer = wx.BoxSizer(wx.VERTICAL)
@ -66,9 +66,12 @@ class Hui(wx.Frame):
btn: wx.Button = wx.Button(self.pnl, label=str(bridge)) btn: wx.Button = wx.Button(self.pnl, label=str(bridge))
self.sizer.Add(btn, 0, wx.EXPAND) self.sizer.Add(btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mbridge=bridge: self.goto_bridge(mbridge), btn) lambda event, mbridge=bridge: self.goto_bridge(
mbridge),
btn)
else: else:
label = "{} {} ({})".format(self.m_unreachable_icon, str(bridge), "unreachable") label = "{} {} ({})".format(self.m_unreachable_icon,
str(bridge), "unreachable")
btn: wx.Button = wx.Button(self.pnl, label=label) btn: wx.Button = wx.Button(self.pnl, label=label)
self.sizer.Add(btn, 0, wx.EXPAND) self.sizer.Add(btn, 0, wx.EXPAND)
@ -76,8 +79,8 @@ class Hui(wx.Frame):
label = "Discover bridge" label = "Discover bridge"
btn: wx.Button = wx.Button(self.pnl, label=label) btn: wx.Button = wx.Button(self.pnl, label=label)
self.sizer.Add(btn, 0, wx.EXPAND) self.sizer.Add(btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON, lambda event: self.discover_new_bridges(),
lambda event: self.discover_new_bridges(), btn) btn)
@redraw @redraw
def add_groups(self, groups: list[HueGroup]): def add_groups(self, groups: list[HueGroup]):
@ -91,10 +94,11 @@ class Hui(wx.Frame):
has_unattached: bool = len(self.cur_bridge.unattached_lights) > 0 has_unattached: bool = len(self.cur_bridge.unattached_lights) > 0
self.sizer.Add(bridge_btn, 0, wx.EXPAND) self.sizer.Add(bridge_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON, lambda event: self.add_bridges(), bridge_btn)
lambda event: self.add_bridges(), bridge_btn)
if has_unattached: if has_unattached:
group_label: wx.StaticText = wx.StaticText(self.pnl, label=" ⚯ Groups ⚯ ", style=wx.ALIGN_CENTER) group_label: wx.StaticText = wx.StaticText(self.pnl,
label=" ⚯ Groups ⚯ ",
style=wx.ALIGN_CENTER)
self.sizer.Add(group_label, 0, wx.EXPAND) self.sizer.Add(group_label, 0, wx.EXPAND)
for group in groups: for group in groups:
inner_sizer: wx.BoxSizer = wx.BoxSizer(orient=wx.HORIZONTAL) inner_sizer: wx.BoxSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
@ -104,17 +108,25 @@ class Hui(wx.Frame):
icon = self.m_on_icon icon = self.m_on_icon
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon) toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
inner_sizer.Add(toggle_btn, 1, wx.EXPAND) inner_sizer.Add(toggle_btn, 1, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(
lambda event, mgroupid=groupid: self.toggle_group(mgroupid), toggle_btn) wx.EVT_BUTTON,
lambda event, mgroupid=groupid: self.toggle_group(mgroupid),
toggle_btn)
label: str = "{}".format(str(group)) label: str = "{}".format(str(group))
group_btn: wx.Button = wx.Button(self.pnl, label=label, style=wx.BU_LEFT) group_btn: wx.Button = wx.Button(self.pnl,
label=label,
style=wx.BU_LEFT)
inner_sizer.Add(group_btn, 4, wx.EXPAND) inner_sizer.Add(group_btn, 4, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(
lambda event, mgroupid=groupid: self.goto_group(mgroupid), group_btn) wx.EVT_BUTTON,
lambda event, mgroupid=groupid: self.goto_group(mgroupid),
group_btn)
self.sizer.Add(inner_sizer, 0, wx.EXPAND) self.sizer.Add(inner_sizer, 0, wx.EXPAND)
if has_unattached: if has_unattached:
unattached_label: wx.StaticText = wx.StaticText(self.pnl, label=" ⚬ Unattached lights ⚬ ", unattached_label: wx.StaticText = wx.StaticText(
style=wx.ALIGN_CENTER) self.pnl,
label=" ⚬ Unattached lights ⚬ ",
style=wx.ALIGN_CENTER)
self.sizer.Add(unattached_label, 0, wx.EXPAND) self.sizer.Add(unattached_label, 0, wx.EXPAND)
for light in self.cur_bridge.unattached_lights: for light in self.cur_bridge.unattached_lights:
inner_sizer = wx.BoxSizer(orient=wx.HORIZONTAL) inner_sizer = wx.BoxSizer(orient=wx.HORIZONTAL)
@ -127,21 +139,29 @@ class Hui(wx.Frame):
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon) toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
inner_sizer.Add(toggle_btn, 1, wx.EXPAND) inner_sizer.Add(toggle_btn, 1, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.toggle_light_and_goto_group(mlightid, lights), lambda event, mlightid=lightid: self.
toggle_light_and_goto_group(mlightid, lights),
toggle_btn) toggle_btn)
label: str = "{}".format(light) label: str = "{}".format(light)
light_btn: wx.Button = wx.Button(self.pnl, label=label, style=wx.BU_LEFT) light_btn: wx.Button = wx.Button(self.pnl,
label=label,
style=wx.BU_LEFT)
inner_sizer.Add(light_btn, 4, wx.EXPAND) inner_sizer.Add(light_btn, 4, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.add_single_light(mlightid, True), light_btn) lambda event, mlightid=lightid: self.
add_single_light(mlightid, True),
light_btn)
self.sizer.Add(inner_sizer, 0, wx.EXPAND) self.sizer.Add(inner_sizer, 0, wx.EXPAND)
def add_manual_discovery_dialog(self) -> bool: def add_manual_discovery_dialog(self) -> bool:
self.sizer.Clear(delete_windows=True) self.sizer.Clear(delete_windows=True)
found_any: bool = False found_any: bool = False
text_entry: wx.TextEntryDialog = wx.TextEntryDialog(self.pnl, "Manually enter IP address of bridge:", text_entry: wx.TextEntryDialog = wx.TextEntryDialog(
caption="Auto discovery failure") self.pnl,
warn_label: wx.StaticText = wx.StaticText(self.pnl, label="Waiting for Button Press on Bridge") "Manually enter IP address of bridge:",
caption="Auto discovery failure")
warn_label: wx.StaticText = wx.StaticText(
self.pnl, label="Waiting for Button Press on Bridge")
if text_entry.ShowModal() == wx.ID_OK: if text_entry.ShowModal() == wx.ID_OK:
ipaddress: str = text_entry.GetValue() ipaddress: str = text_entry.GetValue()
if is_bridge(ipaddress): if is_bridge(ipaddress):
@ -150,12 +170,14 @@ class Hui(wx.Frame):
user_or_error = HueUtils.connect(ipaddress) user_or_error = HueUtils.connect(ipaddress)
while user_or_error.is_error(): while user_or_error.is_error():
user_or_error = HueUtils.connect(ipaddress) user_or_error = HueUtils.connect(ipaddress)
self.m_tinge.append_bridge(HueBridge(ipaddress, user_or_error.get_user(), ipaddress)) self.m_tinge.append_bridge(
HueBridge(ipaddress, user_or_error.get_user(), ipaddress))
found_any = True found_any = True
self.m_tinge.write_all_bridges_to_conf() self.m_tinge.write_all_bridges_to_conf()
else: else:
label = "Supplied IP Address did not match a Bridge.", label = "Supplied IP Address did not match a Bridge.",
failure_msg: wx.GenericMessageDialog = wx.GenericMessageDialog(self.pnl, label, caption="Try again!") failure_msg: wx.GenericMessageDialog = wx.GenericMessageDialog(
self.pnl, label, caption="Try again!")
failure_msg.ShowModal() failure_msg.ShowModal()
return found_any return found_any
@ -170,7 +192,8 @@ class Hui(wx.Frame):
group_btn: wx.Button = wx.Button(self.pnl, label=str(self.cur_bridge)) group_btn: wx.Button = wx.Button(self.pnl, label=str(self.cur_bridge))
self.sizer.Add(group_btn, 0, wx.EXPAND) self.sizer.Add(group_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event: self.add_groups(self.cur_bridge.get_groups()), group_btn) lambda event: self.add_groups(self.cur_bridge.get_groups()),
group_btn)
for light in lights: for light in lights:
inner_sizer = wx.BoxSizer(orient=wx.HORIZONTAL) inner_sizer = wx.BoxSizer(orient=wx.HORIZONTAL)
lightid: int = light.get_id() lightid: int = light.get_id()
@ -182,13 +205,18 @@ class Hui(wx.Frame):
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon) toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
inner_sizer.Add(toggle_btn, 1, wx.EXPAND) inner_sizer.Add(toggle_btn, 1, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.toggle_light_and_goto_group(mlightid, lights), lambda event, mlightid=lightid: self.
toggle_light_and_goto_group(mlightid, lights),
toggle_btn) toggle_btn)
label: str = "{}".format(light) label: str = "{}".format(light)
light_btn: wx.Button = wx.Button(self.pnl, label=label, style=wx.BU_LEFT) light_btn: wx.Button = wx.Button(self.pnl,
label=label,
style=wx.BU_LEFT)
inner_sizer.Add(light_btn, 4, wx.EXPAND) inner_sizer.Add(light_btn, 4, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.add_single_light(mlightid), light_btn) lambda event, mlightid=lightid: self.add_single_light(
mlightid),
light_btn)
self.sizer.Add(inner_sizer, 0, wx.EXPAND) self.sizer.Add(inner_sizer, 0, wx.EXPAND)
@redraw @redraw
@ -203,16 +231,20 @@ class Hui(wx.Frame):
self.SetTitle("Tinge - {}".format(light)) self.SetTitle("Tinge - {}".format(light))
is_on: bool = light.is_on() is_on: bool = light.is_on()
if unattached: if unattached:
group_btn: wx.Button = wx.Button(self.pnl, label=str(self.cur_bridge)) group_btn: wx.Button = wx.Button(self.pnl,
label=str(self.cur_bridge))
self.sizer.Add(group_btn, 0, wx.EXPAND) self.sizer.Add(group_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(
lambda event: self.add_groups(self.cur_bridge.get_groups()), group_btn) wx.EVT_BUTTON,
lambda event: self.add_groups(self.cur_bridge.get_groups()),
group_btn)
else: else:
group: HueGroup = self.cur_group group: HueGroup = self.cur_group
group_btn: wx.Button = wx.Button(self.pnl, label=str(group)) group_btn: wx.Button = wx.Button(self.pnl, label=str(group))
self.sizer.Add(group_btn, 0, wx.EXPAND) self.sizer.Add(group_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event: self.goto_group(self.cur_group.get_id()), group_btn) lambda event: self.goto_group(self.cur_group.get_id()),
group_btn)
# Toggle # Toggle
icon: str = self.m_off_icon icon: str = self.m_off_icon
if is_on: if is_on:
@ -222,54 +254,79 @@ class Hui(wx.Frame):
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon) toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
self.sizer.Add(toggle_btn, 0, wx.EXPAND) self.sizer.Add(toggle_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.toggle_light_and_goto_light(mlightid), lambda event, mlightid=lightid: self.
toggle_light_and_goto_light(mlightid),
toggle_btn) toggle_btn)
# Slider for brightness # Slider for brightness
if is_on: if is_on:
if light.can_set_brightness(): if light.can_set_brightness():
b_label: wx.StaticText = wx.StaticText(self.pnl, label="Brightness") b_label: wx.StaticText = wx.StaticText(self.pnl,
label="Brightness")
self.sizer.Add(b_label, 0, wx.EXPAND) self.sizer.Add(b_label, 0, wx.EXPAND)
b_slider: wx.Slider = wx.Slider(self.pnl, value=light.get_state().get_brightness(), minValue=1, b_slider: wx.Slider = wx.Slider(
maxValue=254) self.pnl,
value=light.get_state().get_brightness(),
minValue=1,
maxValue=254)
self.sizer.Add(b_slider, 0, wx.EXPAND) self.sizer.Add(b_slider, 0, wx.EXPAND)
self.Bind(wx.EVT_SCROLL, self.Bind(
lambda event: self.set_brightness(event, light.get_id()), b_slider) wx.EVT_SCROLL,
lambda event: self.set_brightness(event, light.get_id()),
b_slider)
# Slider for colortemp # Slider for colortemp
if light.can_set_ct(): if light.can_set_ct():
c_label: wx.StaticText = wx.StaticText(self.pnl, label="Color Temperature") c_label: wx.StaticText = wx.StaticText(
self.pnl, label="Color Temperature")
self.sizer.Add(c_label, 0, wx.EXPAND) self.sizer.Add(c_label, 0, wx.EXPAND)
c_slider: wx.Slider = wx.Slider(self.pnl, value=light.get_ct(), minValue=153, maxValue=500) c_slider: wx.Slider = wx.Slider(self.pnl,
value=light.get_ct(),
minValue=153,
maxValue=500)
self.sizer.Add(c_slider, 0, wx.EXPAND) self.sizer.Add(c_slider, 0, wx.EXPAND)
self.Bind(wx.EVT_SCROLL, self.Bind(
lambda event: self.set_colortemp(event, light.get_id()), c_slider) wx.EVT_SCROLL,
lambda event: self.set_colortemp(event, light.get_id()),
c_slider)
# Slider for hue # Slider for hue
if light.can_set_hue(): if light.can_set_hue():
d_label: wx.StaticText = wx.StaticText(self.pnl, label="Hue") d_label: wx.StaticText = wx.StaticText(self.pnl, label="Hue")
self.sizer.Add(d_label, 0, wx.EXPAND) self.sizer.Add(d_label, 0, wx.EXPAND)
d_slider: wx.Slider = wx.Slider(self.pnl, value=light.get_hue(), minValue=0, maxValue=65535) d_slider: wx.Slider = wx.Slider(self.pnl,
value=light.get_hue(),
minValue=0,
maxValue=65535)
self.sizer.Add(d_slider, 0, wx.EXPAND) self.sizer.Add(d_slider, 0, wx.EXPAND)
self.Bind(wx.EVT_SCROLL, self.Bind(wx.EVT_SCROLL,
lambda event: self.set_hue(event, light.get_id()), d_slider) lambda event: self.set_hue(event, light.get_id()),
d_slider)
# Slider for saturation # Slider for saturation
if light.can_set_sat(): if light.can_set_sat():
e_label: wx.StaticText = wx.StaticText(self.pnl, label="Saturation") e_label: wx.StaticText = wx.StaticText(self.pnl,
label="Saturation")
self.sizer.Add(e_label, 0, wx.EXPAND) self.sizer.Add(e_label, 0, wx.EXPAND)
e_slider: wx.Slider = wx.Slider(self.pnl, value=light.get_sat(), minValue=0, maxValue=254) e_slider: wx.Slider = wx.Slider(self.pnl,
value=light.get_sat(),
minValue=0,
maxValue=254)
self.sizer.Add(e_slider, 0, wx.EXPAND) self.sizer.Add(e_slider, 0, wx.EXPAND)
self.Bind(wx.EVT_SCROLL, self.Bind(
lambda event: self.set_saturation(event, light.get_id()), e_slider) wx.EVT_SCROLL,
lambda event: self.set_saturation(event, light.get_id()),
e_slider)
rename_btn: wx.Button = wx.Button(self.pnl, label="Rename") rename_btn: wx.Button = wx.Button(self.pnl, label="Rename")
self.sizer.Add(rename_btn, 0, wx.EXPAND) self.sizer.Add(rename_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.rename_light_and_goto_light(mlightid, unattached), lambda event, mlightid=lightid: self.
rename_light_and_goto_light(mlightid, unattached),
rename_btn) rename_btn)
delete_btn: wx.Button = wx.Button(self.pnl, label="Delete") delete_btn: wx.Button = wx.Button(self.pnl, label="Delete")
self.sizer.Add(delete_btn, 0, wx.EXPAND) self.sizer.Add(delete_btn, 0, wx.EXPAND)
self.Bind(wx.EVT_BUTTON, self.Bind(wx.EVT_BUTTON,
lambda event, mlightid=lightid: self.delete_light_and_goto_group(mlightid), lambda event, mlightid=lightid: self.
delete_light_and_goto_group(mlightid),
delete_btn) delete_btn)
def delete_light_and_goto_group(self, lightid): def delete_light_and_goto_group(self, lightid):
@ -278,7 +335,8 @@ class Hui(wx.Frame):
Args: Args:
lightid (int): The light id of the light to delete lightid (int): The light id of the light to delete
""" """
if self.get_ok_cancel_answer_from_modal("Are you sure you want to delete this light?"): if self.get_ok_cancel_answer_from_modal(
"Are you sure you want to delete this light?"):
light: HueLight = self.cur_bridge.get_light_by_id(lightid) light: HueLight = self.cur_bridge.get_light_by_id(lightid)
light.delete() light.delete()
self.cur_bridge.remove_light(light) self.cur_bridge.remove_light(light)
@ -299,7 +357,9 @@ class Hui(wx.Frame):
user_or_error = HueUtils.connect(bridge['ipaddress']) user_or_error = HueUtils.connect(bridge['ipaddress'])
while user_or_error.is_error(): while user_or_error.is_error():
user_or_error = HueUtils.connect(bridge['ipaddress']) user_or_error = HueUtils.connect(bridge['ipaddress'])
self.m_tinge.append_bridge(HueBridge(bridge['ipaddress'], user_or_error.get_user(), bridge['name'])) self.m_tinge.append_bridge(
HueBridge(bridge['ipaddress'], user_or_error.get_user(),
bridge['name']))
found_any = True found_any = True
self.m_tinge.write_all_bridges_to_conf() self.m_tinge.write_all_bridges_to_conf()
self.add_bridges() self.add_bridges()
@ -317,10 +377,16 @@ class Hui(wx.Frame):
Returns: Returns:
bool: The response from the user bool: The response from the user
""" """
with wx.MessageDialog(self.pnl, message, style=wx.OK | wx.CANCEL | wx.CANCEL_DEFAULT) as dlg: with wx.MessageDialog(self.pnl,
message,
style=wx.OK | wx.CANCEL
| wx.CANCEL_DEFAULT) as dlg:
return dlg.ShowModal() == wx.ID_OK return dlg.ShowModal() == wx.ID_OK
def get_text_answer_from_modal(self, message: str, cap: str, val: str = "") -> str: def get_text_answer_from_modal(self,
message: str,
cap: str,
val: str = "") -> str:
"""Display a text entry and return the content """Display a text entry and return the content
Args: Args:
@ -331,7 +397,8 @@ class Hui(wx.Frame):
Returns: Returns:
str: The response from the user str: The response from the user
""" """
with wx.TextEntryDialog(self.pnl, message, caption=cap, value=val) as dlg: with wx.TextEntryDialog(self.pnl, message, caption=cap,
value=val) as dlg:
dlg.ShowModal() dlg.ShowModal()
answer: str = dlg.GetValue() answer: str = dlg.GetValue()
return answer return answer
@ -365,7 +432,8 @@ class Hui(wx.Frame):
Args: Args:
lightid ([type]): The light id of the light to rename/display lightid ([type]): The light id of the light to rename/display
""" """
newname: str = self.get_text_answer_from_modal("Set new name", "New name:") newname: str = self.get_text_answer_from_modal("Set new name",
"New name:")
if newname: if newname:
self.cur_bridge.get_light_by_id(lightid).rename(newname) self.cur_bridge.get_light_by_id(lightid).rename(newname)
self.add_single_light(lightid, unattached) self.add_single_light(lightid, unattached)
@ -432,7 +500,8 @@ class Hui(wx.Frame):
self.cur_bridge.get_light_by_id(lightid).toggle() self.cur_bridge.get_light_by_id(lightid).toggle()
self.add_single_light(lightid) self.add_single_light(lightid)
def toggle_light_and_goto_group(self, lightid: int, lights: list[HueLight]): def toggle_light_and_goto_group(self, lightid: int,
lights: list[HueLight]):
"""Combo call back for toggle and goto group """Combo call back for toggle and goto group
Args: Args:

@ -12,13 +12,15 @@ class HueBridge:
"""This class represents a Hue Bridge """This class represents a Hue Bridge
""" """
def __init__(self, ipaddress: str, username: str, name: str = "", is_reachable: bool = True): def __init__(self, ipaddress: str, username: str,
name: str = "", is_reachable: bool = True):
""" Constructor """ Constructor
Args: Args:
ipaddress (str): The ip address of the bridge ipaddress (str): The ip address of the bridge
username (str): The username for this app for this 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. name (str, optional): A human readable name for this bridge.
Is set to ipaddress, if not supplied.
""" """
self.m_ipaddress: str = ipaddress self.m_ipaddress: str = ipaddress
self.m_username: str = username self.m_username: str = username
@ -58,8 +60,8 @@ class HueBridge:
return self.m_name return self.m_name
def append_new_lights(self) -> bool: def append_new_lights(self) -> bool:
"""If any new lights were discovered in discover_new_lights(), they can be appended to this bridges """If any new lights were discovered in discover_new_lights(),
list of lights with this function they can be appended to this bridges list of lights with this function
Returns: Returns:
bool: True if the request was ok, otherwise False bool: True if the request was ok, otherwise False
@ -70,36 +72,44 @@ class HueBridge:
if key != 'lastscan': if key != 'lastscan':
path: str = "{}/lights/{}".format(self.m_username, key) path: str = "{}/lights/{}".format(self.m_username, key)
response = make_request(self.m_ipaddress, path) response = make_request(self.m_ipaddress, path)
self.m_lights.append(HueLight(int(key), response.json(), self.get_ipaddress(), self.get_user())) self.m_lights.append(HueLight(int(key), response.json(),
self.get_ipaddress(), self.get_user()))
return response.ok return response.ok
def create_group(self, lights: list[HueLight], name: str, group_type: str = "LightGroup", def create_group(self, lights: list[HueLight], name: str,
group_type: str = "LightGroup",
group_class: str = "Other") -> bool: group_class: str = "Other") -> bool:
"""Create a group from a list of lights """Create a group from a list of lights
Args: Args:
lights (list[HueLight]): a list of lights to group lights (list[HueLight]): a list of lights to group
name (str): The name of the new group name (str): The name of the new group
group_type (str, optional): The group type can be LightGroup, Room or either Luminaire or group_type (str, optional): The group type can be LightGroup,
LightSource if a Multisource Luminaire is present in the system. Room or either Luminaire or
Defaults to "LightGroup". LightSource if a Multisource
group_class (str, optional): Category of Room Types. Defaults to "Other". Luminaire is present in the system.
Defaults to "LightGroup".
group_class (str, optional): Category of Room Types.
Defaults to "Other".
Returns: Returns:
bool: True if creation was a success, otherwise False bool: True if creation was a success, otherwise False
""" """
path = "{}/groups".format(self.get_user()) path = "{}/groups".format(self.get_user())
method = "POST" method = "POST"
data: dict = {'lights': [], 'name': name, 'type': group_type, 'class': group_class} data: dict = {'lights': [], 'name': name,
'type': group_type, 'class': group_class}
for light in lights: for light in lights:
data['lights'].append(str(light.get_id())) data['lights'].append(str(light.get_id()))
response = make_request(self.get_ipaddress(), path, method, json.dumps(data)) response = make_request(self.get_ipaddress(),
path, method, json.dumps(data))
r_json = response.json() r_json = response.json()
if 'success' in r_json.keys(): if 'success' in r_json.keys():
new_id = r_json['success']['id'] new_id = r_json['success']['id']
new_path = "{}/groups/{}".format(self.get_user(), new_id) new_path = "{}/groups/{}".format(self.get_user(), new_id)
new_group = make_request(self.get_ipaddress(), new_path).json() 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())) self.m_groups.append(HueGroup(int(new_id), lights, new_group,
self.get_ipaddress(), self.get_user()))
return True return True
else: else:
return False return False
@ -117,7 +127,8 @@ class HueBridge:
lights: list[HueLight] = list() lights: list[HueLight] = list()
for light in value['lights']: for light in value['lights']:
lights.append(self.get_light_by_id(int(light))) lights.append(self.get_light_by_id(int(light)))
groups.append(HueGroup(int(key), lights, value, self.get_ipaddress(), self.get_user())) groups.append(HueGroup(int(key), lights, value,
self.get_ipaddress(), self.get_user()))
return groups return groups
def discover_lights(self) -> list[HueLight]: def discover_lights(self) -> list[HueLight]:
@ -130,7 +141,8 @@ class HueBridge:
response = make_request(self.m_ipaddress, path) response = make_request(self.m_ipaddress, path)
lights: list[HueLight] = list() lights: list[HueLight] = list()
for key, value in json.loads(response.text).items(): for key, value in json.loads(response.text).items():
lights.append(HueLight(int(key), value, self.get_ipaddress(), self.get_user())) lights.append(HueLight(int(key),
value, self.get_ipaddress(), self.get_user()))
return lights return lights
def discover_new_lights(self, light_ids: Union[None, list[int]] = None) -> bool: def discover_new_lights(self, light_ids: Union[None, list[int]] = None) -> bool:
@ -211,7 +223,8 @@ class HueBridge:
if lightid != "lastscan": if lightid != "lastscan":
print(lightid) print(lightid)
if not self.get_light_by_id(int(lightid)): if not self.get_light_by_id(int(lightid)):
lightpath: str = "{}/lights/{}".format(self.m_username, int(lightid)) lightpath: str = "{}/lights/{}".format(
self.m_username, int(lightid))
lightresponse = make_request(self.m_ipaddress, lightpath) lightresponse = make_request(self.m_ipaddress, lightpath)
newlights.append( newlights.append(
HueLight(int(lightid), lightresponse.json(), self.get_ipaddress(), self.get_user())) HueLight(int(lightid), lightresponse.json(), self.get_ipaddress(), self.get_user()))

@ -19,7 +19,8 @@ class HueGroup:
"""Constructor """Constructor
Args: Args:
data_slice (dict): The part of the data structure that concerns this Action data_slice (dict): The part of the data structure that
concerns this Action
""" """
keys = data_slice.keys() keys = data_slice.keys()
self.m_on: bool = data_slice['on'] self.m_on: bool = data_slice['on']
@ -52,14 +53,15 @@ class HueGroup:
class State: class State:
"""A hueGroup.State represents the collective state of the group """A hueGroup.State represents the collective state of the group
""" """
def __init__(self, data_slice: dict): def __init__(self, data_slice: dict):
"""Constructor """Constructor
Args: Args:
data_slice (dict): The part of the data structure that concerns this State data_slice (dict): The part of the data structure
that concerns this State
""" """
self.m_all_on: bool = data_slice['all_on'] self.m_all_on: bool = data_slice['all_on']
self.m_any_on: bool = data_slice['any_on'] self.m_any_on: bool = data_slice['any_on']
@ -199,7 +201,8 @@ class HueGroup:
Returns: Returns:
requests.Response: The API response requests.Response: The API response
""" """
path: str = "{}/groups/{}/action".format(self.m_parent_bridge_user, self.m_id) path: str = "{}/groups/{}/action".format(
self.m_parent_bridge_user, self.m_id)
method: str = "PUT" method: str = "PUT"
response = make_request(self.m_parent_bridge_ip, path, method, state) response = make_request(self.m_parent_bridge_ip, path, method, state)
self.update_state() self.update_state()

Loading…
Cancel
Save