experiments
This commit is contained in:
commit
c62aa93ae0
3 changed files with 410 additions and 0 deletions
114
discovery/main.go
Normal file
114
discovery/main.go
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
package discovery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/amimof/huego"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UserInfo is the saved data struture of a Hue app connection
|
||||||
|
type UserInfo struct {
|
||||||
|
User string
|
||||||
|
}
|
||||||
|
|
||||||
|
func DiscoverAndConnectFromConfig(appName string) (*huego.Bridge, error) {
|
||||||
|
data := make(map[string]UserInfo)
|
||||||
|
u, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := filepath.Join(u.HomeDir, ".config/hue-barak")
|
||||||
|
_, err = os.Stat(filename)
|
||||||
|
if err == nil {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.NewDecoder(f).Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
ui, ok := data[appName]
|
||||||
|
if !ok {
|
||||||
|
ui = UserInfo{}
|
||||||
|
}
|
||||||
|
b, err := huego.Discover()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ui.User != "" {
|
||||||
|
newb := b.Login(ui.User)
|
||||||
|
return newb, nil
|
||||||
|
}
|
||||||
|
fmt.Println("Please press the Hue Bridge button, then press Enter")
|
||||||
|
fmt.Scanln()
|
||||||
|
user, err := b.CreateUser(appName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data[appName] = UserInfo{User: user}
|
||||||
|
|
||||||
|
b = b.Login(user)
|
||||||
|
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
defer f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = json.NewEncoder(f).Encode(data)
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
b, err := DiscoverAndConnectFromConfig("barak-hue-test")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rules, err := b.GetRules()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for i, r := range rules {
|
||||||
|
fmt.Println(i, r.ID, r.Name)
|
||||||
|
//for _, act := range r.Actions {
|
||||||
|
//fmt.Printf("\t%#v\n", act)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
testRule := huego.Rule{Actions: rules[0].Actions}
|
||||||
|
t, _ := json.Marshal(testRule)
|
||||||
|
fmt.Println(string(t))
|
||||||
|
|
||||||
|
l, err := b.GetGroups()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for i, r := range l {
|
||||||
|
fmt.Println(i, r.ID, r.Name, r.IsOn())
|
||||||
|
//for _, s := range r.Lights {
|
||||||
|
//fmt.Printf("\t%s\n", s)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := b.GetSensors()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for i, r := range s {
|
||||||
|
fmt.Println(i, r.ID, r.Name)
|
||||||
|
//for _, s := range r.Lights {
|
||||||
|
//fmt.Printf("\t%s\n", s)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
142
gui/main.go
Normal file
142
gui/main.go
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
154
main.go
Normal file
154
main.go
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.barakmich.com/barak/hue/discovery"
|
||||||
|
"github.com/amimof/huego"
|
||||||
|
"github.com/lucasb-eyer/go-colorful"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setLightToHex(l *huego.Light, hex string, tTenths int) error {
|
||||||
|
return setLightToHexBright(l, hex, -1, tTenths)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setLightToHexBright(l *huego.Light, hex string, bright int, tTenths int) error {
|
||||||
|
c, _ := colorful.Hex(hex)
|
||||||
|
xc, yc, yz := c.Xyy()
|
||||||
|
var bout uint8
|
||||||
|
if bright < 0 {
|
||||||
|
bout = uint8(255 * yz)
|
||||||
|
} else {
|
||||||
|
bout = uint8(bright)
|
||||||
|
}
|
||||||
|
return l.SetState(huego.State{
|
||||||
|
On: true,
|
||||||
|
TransitionTime: uint16(tTenths),
|
||||||
|
ColorMode: "xy",
|
||||||
|
Xy: []float32{float32(xc), float32(yc)},
|
||||||
|
Bri: bout,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTransition(l *huego.Light, ret chan *huego.Light) {
|
||||||
|
setLightToHex(l, "#aaaaaa", 7)
|
||||||
|
time.Sleep(800 * time.Millisecond)
|
||||||
|
setLightToHex(l, "#5555ff", 7)
|
||||||
|
time.Sleep(700 * time.Millisecond)
|
||||||
|
ret <- l
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSnowAmbiance(lights []*huego.Light) {
|
||||||
|
for _, x := range lights {
|
||||||
|
setLightToHex(x, "#5555ff", 0)
|
||||||
|
}
|
||||||
|
var ready []*huego.Light
|
||||||
|
ret := make(chan *huego.Light, 100)
|
||||||
|
ready = lights
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case l := <-ret:
|
||||||
|
ready = append(ready, l)
|
||||||
|
case <-time.Tick(100 * time.Millisecond):
|
||||||
|
if rand.Float32() < 0.03 {
|
||||||
|
if len(ready) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i := rand.Intn(len(ready))
|
||||||
|
l := ready[i]
|
||||||
|
ready = append(ready[:i], ready[i+1:]...)
|
||||||
|
go runTransition(l, ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRedTransition(l *huego.Light, c chan *huego.Light) {
|
||||||
|
setLightToHex(l, "#ff0000", 0)
|
||||||
|
c <- l
|
||||||
|
}
|
||||||
|
|
||||||
|
func runGreenTransition(l *huego.Light, c chan *huego.Light) {
|
||||||
|
setLightToHex(l, "#009900", 0)
|
||||||
|
c <- l
|
||||||
|
}
|
||||||
|
|
||||||
|
func runChristmas(lights []*huego.Light) {
|
||||||
|
var red []*huego.Light
|
||||||
|
var green []*huego.Light
|
||||||
|
redc := make(chan *huego.Light, 100)
|
||||||
|
greenc := make(chan *huego.Light, 100)
|
||||||
|
for _, x := range lights {
|
||||||
|
if rand.Float32() < 0.5 {
|
||||||
|
setLightToHex(x, "#ff0000", 0)
|
||||||
|
red = append(red, x)
|
||||||
|
} else {
|
||||||
|
setLightToHex(x, "#009900", 0)
|
||||||
|
green = append(green, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case x := <-redc:
|
||||||
|
red = append(red, x)
|
||||||
|
case x := <-greenc:
|
||||||
|
green = append(green, x)
|
||||||
|
case <-time.Tick(1000 * time.Millisecond):
|
||||||
|
if len(red)+len(green) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var selector = red
|
||||||
|
toRed := false
|
||||||
|
i := rand.Intn(len(red) + len(green))
|
||||||
|
if i >= len(red) {
|
||||||
|
i = i - len(red)
|
||||||
|
selector = green
|
||||||
|
toRed = true
|
||||||
|
}
|
||||||
|
l := selector[i]
|
||||||
|
selector = append(selector[:i], selector[i+1:]...)
|
||||||
|
if toRed {
|
||||||
|
go runRedTransition(l, redc)
|
||||||
|
} else {
|
||||||
|
go runGreenTransition(l, greenc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bridge, err := discovery.DiscoverAndConnectFromConfig("barak-hue-test")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
groups, err := bridge.GetGroups()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var all huego.Group
|
||||||
|
found := false
|
||||||
|
for _, x := range groups {
|
||||||
|
if x.Name == "All Colors" {
|
||||||
|
found = true
|
||||||
|
all = x
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(all)
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
panic("couldn't find it")
|
||||||
|
}
|
||||||
|
lightaddr := make([]*huego.Light, len(all.Lights))
|
||||||
|
for i, x := range all.Lights {
|
||||||
|
n, _ := strconv.Atoi(x)
|
||||||
|
lightaddr[i], err = bridge.GetLight(n)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runChristmas(lightaddr)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue