parent
00c6da8f0a
commit
273e111477
@ -1,9 +1,241 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from tinge import Tinge
|
||||
from typing import Union
|
||||
|
||||
import wx
|
||||
import wx.lib.scrolledpanel as scrolled
|
||||
|
||||
from tinge import Tinge, HueBridge, HueGroup, HueLight
|
||||
|
||||
|
||||
class Hui(wx.Frame):
|
||||
"""This is the Hue GUI class
|
||||
|
||||
Args:
|
||||
wx (Frame): Parent class
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
"""Constructor
|
||||
"""
|
||||
super().__init__(*args, **kw)
|
||||
self.m_on_icon: str = '☼'
|
||||
self.m_off_icon: str = '☾'
|
||||
self.m_tinge: Tinge = Tinge()
|
||||
self.m_bridges: list[HueBridge] = self.m_tinge.get_bridges()
|
||||
self.cur_bridge: Union[None, HueBridge] = None
|
||||
self.cur_group: Union[None, HueGroup] = None
|
||||
# create a panel in the frame
|
||||
self.pnl: scrolled.ScrolledPanel = scrolled.ScrolledPanel(self, -1, style=wx.VSCROLL)
|
||||
self.pnl.SetupScrolling()
|
||||
# and create a sizer to manage the layout of child widgets
|
||||
self.sizer: wx.BoxSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.pnl.SetSizer(self.sizer)
|
||||
self.add_bridges()
|
||||
|
||||
def add_bridges(self):
|
||||
"""Add bridges to sizer, the entry point of the program
|
||||
"""
|
||||
self.sizer.Clear(delete_windows=True)
|
||||
if self.m_bridges:
|
||||
for bridge in self.m_bridges:
|
||||
btn: wx.Button = wx.Button(self.pnl, label=str(bridge))
|
||||
self.sizer.Add(btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mbridge=bridge: self.goto_bridge(mbridge), btn)
|
||||
else:
|
||||
btn: wx.Button = wx.Button(self.pnl, label="Discover bridges")
|
||||
self.sizer.Add(btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event: self.discover_new_bridges(), btn)
|
||||
self.sizer.Layout()
|
||||
|
||||
def add_groups(self, groups: list[HueGroup]):
|
||||
"""This will add the groups to the sizer, when coming down from a bridge, or up from a light
|
||||
|
||||
Args:
|
||||
groups (list[HueGroup]): The groups to display
|
||||
"""
|
||||
self.sizer.Clear(delete_windows=True)
|
||||
bridge_btn: wx.Button = wx.Button(self.pnl, label=str(self.cur_bridge))
|
||||
self.sizer.Add(bridge_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event: self.add_bridges(), bridge_btn)
|
||||
for group in groups:
|
||||
inner_sizer: wx.BoxSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
|
||||
groupid: int = group.get_id()
|
||||
icon: str = self.m_off_icon
|
||||
if group.is_any_on():
|
||||
icon = self.m_on_icon
|
||||
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
|
||||
inner_sizer.Add(toggle_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mgroupid=groupid: self.toggle_group(mgroupid), toggle_btn)
|
||||
label: str = str(group)
|
||||
group_btn: wx.Button = wx.Button(self.pnl, label=label)
|
||||
inner_sizer.Add(group_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mgroupid=groupid: self.goto_group(mgroupid), group_btn)
|
||||
self.sizer.Add(inner_sizer, 0, wx.EXPAND)
|
||||
self.sizer.Layout()
|
||||
|
||||
# noinspection PyDefaultArgument
|
||||
def add_lights(self, lights: list[HueLight]):
|
||||
"""This will add the lights from a group to the sizer
|
||||
|
||||
Args:
|
||||
lights (list[HueLight]): The lights to display
|
||||
"""
|
||||
self.sizer.Clear(delete_windows=True)
|
||||
group_btn: wx.Button = wx.Button(self.pnl, label=str(self.cur_group))
|
||||
self.sizer.Add(group_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event: self.add_groups(self.cur_bridge.get_groups()), group_btn)
|
||||
for light in lights:
|
||||
inner_sizer = wx.BoxSizer(orient=wx.HORIZONTAL)
|
||||
lightid: int = light.get_id()
|
||||
icon: str = self.m_off_icon
|
||||
if light.is_on():
|
||||
icon = self.m_on_icon
|
||||
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
|
||||
inner_sizer.Add(toggle_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mlightid=lightid, mlights=lights: self.toggle_light_and_goto_group(mlightid,
|
||||
mlights),
|
||||
toggle_btn)
|
||||
label: str = "{}".format(light)
|
||||
light_btn: wx.Button = wx.Button(self.pnl, label=label)
|
||||
inner_sizer.Add(light_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mlightid=lightid: self.goto_light(mlightid), light_btn)
|
||||
self.sizer.Add(inner_sizer, 0, wx.EXPAND)
|
||||
self.sizer.Layout()
|
||||
|
||||
def goto_bridge(self, bridge: HueBridge):
|
||||
"""Call back for a bridge button
|
||||
|
||||
Args:
|
||||
bridge (HueBridge): The bridge to display
|
||||
"""
|
||||
self.cur_bridge = bridge
|
||||
groups: list[HueGroup] = bridge.get_groups()
|
||||
if groups:
|
||||
self.add_groups(groups)
|
||||
else:
|
||||
self.add_lights(bridge.get_lights())
|
||||
|
||||
def discover_new_bridges(self):
|
||||
"""Call back for button that is displayed if no bridges were found
|
||||
"""
|
||||
self.m_tinge.discover_new_bridges()
|
||||
self.add_bridges()
|
||||
|
||||
def toggle_group(self, groupid: int):
|
||||
"""Toggle the lights of a group
|
||||
|
||||
Args:
|
||||
groupid (int): The group id of the group to toggle
|
||||
"""
|
||||
self.cur_bridge.get_group_by_id(groupid).toggle()
|
||||
self.add_groups(self.cur_bridge.get_groups())
|
||||
|
||||
def goto_group(self, groupid: int):
|
||||
"""Call back for group button
|
||||
|
||||
Args:
|
||||
groupid (int): The group id of the group to display
|
||||
"""
|
||||
group = self.cur_bridge.get_group_by_id(groupid)
|
||||
self.cur_group = group
|
||||
self.add_lights(group.get_lights())
|
||||
|
||||
def toggle_light_and_goto_group(self, lightid: int, lights: list[HueLight]):
|
||||
"""Combo call back for toggle and goto group
|
||||
|
||||
Args:
|
||||
lightid (int): The light id oof the light to toggle
|
||||
lights (list[HueLight]): The lights to display after toggle
|
||||
"""
|
||||
self.cur_bridge.get_light_by_id(lightid).toggle()
|
||||
self.add_lights(lights)
|
||||
|
||||
def goto_light(self, lightid: int):
|
||||
"""Call back for light button
|
||||
|
||||
Args:
|
||||
lightid (int): The light id of the light to display
|
||||
"""
|
||||
light: HueLight = self.cur_bridge.get_light_by_id(lightid)
|
||||
is_on: bool = light.is_on()
|
||||
self.sizer.Clear(delete_windows=True)
|
||||
group: HueGroup = self.cur_group
|
||||
group_btn: wx.Button = wx.Button(self.pnl, label=str(group))
|
||||
self.sizer.Add(group_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event: self.goto_group(self.cur_group.get_id()), group_btn)
|
||||
# Toggle
|
||||
icon: str = self.m_off_icon
|
||||
if is_on:
|
||||
icon = self.m_on_icon
|
||||
toggle_btn: wx.Button = wx.Button(self.pnl, label=icon)
|
||||
self.sizer.Add(toggle_btn, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_BUTTON,
|
||||
lambda event, mlightid=lightid: self.toggle_light_and_goto_light(mlightid),
|
||||
toggle_btn)
|
||||
|
||||
# Slider for brightness
|
||||
if is_on and light.get_brightness() > 0:
|
||||
b_label: wx.StaticText = wx.StaticText(self.pnl, label="Brightness")
|
||||
self.sizer.Add(b_label, 0, wx.EXPAND)
|
||||
b_slider: wx.Slider = wx.Slider(self.pnl, value=light.get_state().get_brightness(), minValue=1,
|
||||
maxValue=254)
|
||||
self.sizer.Add(b_slider, 0, wx.EXPAND)
|
||||
self.Bind(wx.EVT_SCROLL_THUMBRELEASE,
|
||||
lambda event: self.set_brightness(event, light.get_id()), b_slider)
|
||||
# Slider for colortemp
|
||||
if is_on and light.can_set_ct():
|
||||
c_label: wx.StaticText = wx.StaticText(self.pnl, label="Color Temperature")
|
||||
self.sizer.Add(c_label, 0, wx.EXPAND)
|
||||
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.Bind(wx.EVT_SCROLL_THUMBRELEASE,
|
||||
lambda event: self.set_colortemp(event, light.get_id()), c_slider)
|
||||
self.sizer.Layout()
|
||||
|
||||
def set_brightness(self, event: wx.ScrollEvent, lightid: int):
|
||||
"""Call back for brightness slider
|
||||
|
||||
Args:
|
||||
event (wx.ScrollEvent): The scroll event to react to
|
||||
lightid (int): The light id of the light to adjust brightness of
|
||||
"""
|
||||
bri: int = event.GetPosition()
|
||||
light: HueLight = self.cur_bridge.get_light_by_id(lightid)
|
||||
light.set_brightness(bri)
|
||||
|
||||
def toggle_light_and_goto_light(self, lightid):
|
||||
"""Combo call back to toggle a light and display that light again
|
||||
|
||||
Args:
|
||||
lightid ([type]): The light id of the light to toggle/display
|
||||
"""
|
||||
self.cur_bridge.get_light_by_id(lightid).toggle()
|
||||
self.goto_light(lightid)
|
||||
|
||||
def set_colortemp(self, event, lightid):
|
||||
"""Call back for colortemp slider
|
||||
|
||||
Args:
|
||||
event (wx.ScrollEvent): The scroll event to react to
|
||||
lightid (int): The light id of the light to adjust colortemp of
|
||||
"""
|
||||
ct: int = event.GetPosition()
|
||||
light: HueLight = self.cur_bridge.get_light_by_id(lightid)
|
||||
light.set_ct(ct)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
m_tinge = Tinge()
|
||||
bridge = m_tinge.get_bridges()[0]
|
||||
print(bridge.discover_new_lights())
|
||||
print(bridge.append_new_lights())
|
||||
app = wx.App()
|
||||
frm = Hui(None, title="Tinge")
|
||||
frm.Show()
|
||||
app.MainLoop()
|
||||
|
Loading…
Reference in new issue