package main import ( "fmt" "sort" "time" "git.barakmich.com/barak/hue/discovery" "github.com/amimof/huego" "github.com/andlabs/ui" "github.com/lucasb-eyer/go-colorful" "github.com/maruel/temperature" ) type groupList struct { box *ui.Box groups []*group } type group struct { group huego.Group box *ui.Box cb *ui.Checkbox color *ui.ColorButton } type uiModel struct { gl *groupList } var bridge *huego.Bridge func (u *uiModel) update() { var err error if bridge == nil { bridge, err = discovery.DiscoverAndConnectFromConfig("barak-hue-test") if err != nil { ui.QueueMain(func() { ui.Quit() }) } } groups, err := bridge.GetGroups() if err != nil { panic(err) } ui.QueueMain(func() { u.gl.update(groups) }) } func newGroup() *group { g := &group{} g.box = ui.NewHorizontalBox() g.cb = ui.NewCheckbox("") g.color = ui.NewColorButton() g.box.Append(g.color, false) g.box.Append(g.cb, false) g.cb.OnToggled(g.onToggle) return g } func (gl *groupList) update(groups []huego.Group) { sort.Slice(groups, func(i, j int) bool { return groups[i].ID < groups[j].ID }) for len(gl.groups) < len(groups) { g := newGroup() gl.groups = append(gl.groups, g) gl.box.Append(g.box, false) } for i, g := range gl.groups { g.group = groups[i] g.update() } } func (g *group) update() { g.cb.SetText(fmt.Sprintf("%d %s : %s", g.group.ID, g.group.Name, fmt.Sprint(g.group.State.Xy, g.group.State.Bri, g.group.State.Hue, g.group.State.Sat))) if g.group.State.ColorMode == "xy" { c := colorful.Xyy(float64(g.group.State.Xy[0]), float64(g.group.State.Xy[1]), (float64(g.group.State.Bri)/(255.0*1.5))+0.33) r, gr, b := c.LinearRgb() g.color.SetColor(r, gr, b, 1.0) } else if g.group.State.ColorMode == "ct" { r, gr, b := temperature.ToRGB(uint16(1000000.0 / float64(g.group.State.Ct))) g.color.SetColor(float64(r)/255.0, float64(gr)/255.0, float64(b)/255.0, 1.0) } else { b := float64(g.group.State.Bri) / 255.0 g.color.SetColor(b, b, b, 1.0) } g.cb.SetChecked(g.group.IsOn()) } func (g *group) onToggle(c *ui.Checkbox) { fmt.Println("toggling", g.group.ID) var err error if c.Checked() { err = g.group.On() } else { err = g.group.Off() } if err != nil { panic(err) } } func main() { closer := make(chan bool) err := ui.Main(func() { gl := &groupList{} uiModel := &uiModel{ gl: gl, } gl.box = ui.NewVerticalBox() window := ui.NewWindow("Hue UI", 200, 100, false) window.SetMargined(true) window.SetChild(gl.box) window.OnClosing(func(*ui.Window) bool { ui.Quit() return true }) fmt.Println("whatup") go updater(closer, uiModel) window.Show() }) fmt.Println("outside") if err != nil { panic(err) } close(closer) } func updater(closer chan bool, um *uiModel) { um.update() for { select { case <-closer: return case <-time.After(2 * time.Second): fmt.Println("tick") um.update() } } }