literally had to make these changes before I could turn my hallway light back on :^)

This commit is contained in:
kayos@tcp.direct 2022-09-06 16:31:44 -07:00
parent eeea125396
commit 7a33b30802
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
7 changed files with 124 additions and 73 deletions

@ -261,7 +261,7 @@ func getHist() []string {
func StartCLI() { func StartCLI() {
log = config.GetLogger() log = config.GetLogger()
processBridges() processBridges()
grpmap, err := getGroupMap() grpmap, err := ziggy.GetGroupMap()
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("error getting group map") log.Fatal().Err(err).Msg("error getting group map")
} }

@ -36,13 +36,10 @@ var bridgeCMD = map[string]reactor{
} }
func cmdLights(br *ziggy.Bridge, args []string) error { func cmdLights(br *ziggy.Bridge, args []string) error {
if len(br.HueLights) == 0 { for name, l := range ziggy.GetLightMap() {
return errors.New("no lights found") log.Info().
}
for _, l := range br.HueLights {
log.Info().Str("caller", l.Name).
Int("ID", l.ID).Str("type", l.ProductName). Int("ID", l.ID).Str("type", l.ProductName).
Str("model", l.ModelID).Bool("on", l.IsOn()).Msgf("%v", l.State) Str("model", l.ModelID).Bool("on", l.IsOn()).Msgf("[+] %s", name)
} }
return nil return nil
} }
@ -156,7 +153,8 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
) )
var ( var (
groupmap map[string]*huego.Group groupMap map[string]*huego.Group
lightMap map[string]*huego.Light
actions []action actions []action
currentState *huego.State currentState *huego.State
argHead = -1 argHead = -1
@ -170,9 +168,9 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
} }
log.Trace().Int("argHead", argHead).Msg(args[argHead]) log.Trace().Int("argHead", argHead).Msg(args[argHead])
switch args[argHead] { switch args[argHead] {
case "group", "g", "grp": case "group", "g":
var err error var err error
groupmap, err = getGroupMap() groupMap, err = ziggy.GetGroupMap()
if err != nil { if err != nil {
return err return err
} }
@ -180,7 +178,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
return errors.New("no group specified") return errors.New("no group specified")
} }
argHead++ argHead++
g, ok := groupmap[strings.TrimSpace(args[argHead])] g, ok := groupMap[strings.TrimSpace(args[argHead])]
if !ok { if !ok {
return fmt.Errorf("group %s not found (argHead: %d)", args[argHead], argHead) return fmt.Errorf("group %s not found (argHead: %d)", args[argHead], argHead)
} }
@ -188,6 +186,21 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
args[argHead], argHead, args[argHead], argHead,
) )
target = g target = g
case "light", "l":
lightMap = ziggy.GetLightMap()
if len(args) <= argHead-1 {
return errors.New("no light specified")
}
argHead++
l, ok := lightMap[strings.TrimSpace(args[argHead])]
if !ok {
return fmt.Errorf("light %s not found (argHead: %d)", args[argHead], argHead)
}
if extraDebug {
log.Trace().Str("group", l.Name).Msgf("found light %s via args[%d]",
args[argHead], argHead)
}
target = l
case "on": case "on":
actions = append(actions, target.On) actions = append(actions, target.On)
case "off": case "off":
@ -339,33 +352,8 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
return nil return nil
} }
func getGroupMap() (map[string]*huego.Group, error) {
var groupmap = make(map[string]*huego.Group)
for _, br := range ziggy.Lucifer.Bridges {
gs, err := br.GetGroups()
if err != nil {
return nil, err
}
for i, g := range gs {
grp, gerr := br.GetGroup(i)
if gerr != nil {
log.Warn().Msgf("[%s] %w", g.Name, gerr)
continue
}
var count = 1
groupName := g.Name
for _, ok := groupmap[groupName]; ok; _, ok = groupmap[groupName] {
groupName = fmt.Sprintf("%s_%d", g.Name, count)
}
groupmap[groupName] = grp
}
}
return groupmap, nil
}
func cmdGroups(br *ziggy.Bridge, args []string) error { func cmdGroups(br *ziggy.Bridge, args []string) error {
groupmap, err := getGroupMap() groupmap, err := ziggy.GetGroupMap()
if err != nil { if err != nil {
return err return err
} }

@ -101,9 +101,19 @@ func init() {
{Suggest: cli.Suggest{Text: "light", Description: "target light"}}, {Suggest: cli.Suggest{Text: "light", Description: "target light"}},
} }
for _, sug := range suggestions[1] { for _, sug := range suggestions[1] {
sug.requires = map[int][]string{0: {"set", "s"}} sug.requires = map[int][]string{0: {"delete", "del", "set", "s"}}
sug.root = false sug.root = false
} }
delCompletion := []completion{
{Suggest: cli.Suggest{Text: "scene", Description: "target scene"}},
{Suggest: cli.Suggest{Text: "schedule", Description: "target schedule"}},
{Suggest: cli.Suggest{Text: "sensor", Description: "target sensor"}},
}
for _, sug := range delCompletion {
sug.requires = map[int][]string{0: {"delete", "del"}}
sug.root = false
}
suggestions[1] = append(suggestions[1], delCompletion...)
} }
func processGroups(grps map[string]*huego.Group) { func processGroups(grps map[string]*huego.Group) {
@ -119,7 +129,7 @@ func processGroups(grps map[string]*huego.Group) {
Description: "Group" + suffix, Description: "Group" + suffix,
}, },
requires: map[int][]string{ requires: map[int][]string{
0: {"set", "s"}, 0: {"set", "s", "delete", "del"},
1: {"group", "g"}, 1: {"group", "g"},
}, },
root: false, root: false,
@ -128,7 +138,7 @@ func processGroups(grps map[string]*huego.Group) {
} }
func processLights() { func processLights() {
for lt, l := range ziggy.Lucifer.Lights { for lt, l := range ziggy.GetLightMap() {
suffix := "" suffix := ""
if l.Type != "" { if l.Type != "" {
suffix = " (" + l.Type + ")" suffix = " (" + l.Type + ")"
@ -140,7 +150,7 @@ func processLights() {
Description: "Light" + suffix, Description: "Light" + suffix,
}, },
requires: map[int][]string{ requires: map[int][]string{
0: {"set", "s"}, 0: {"set", "s", "delete", "del"},
1: {"light", "l"}, 1: {"light", "l"},
}, },
root: false, root: false,

@ -33,7 +33,7 @@ func cpuLoad(ctx context.Context) (chan int, error) {
func CPULoadGradient(ctx context.Context, colors ...string) (chan colorful.Color, error) { func CPULoadGradient(ctx context.Context, colors ...string) (chan colorful.Color, error) {
grad, err := colorgrad.NewGradient(). grad, err := colorgrad.NewGradient().
HtmlColors(colors...). HtmlColors(colors...).
Domain(0, 80). Domain(0, 100).
Build() Build()
if err != nil { if err != nil {
return nil, err return nil, err

@ -44,7 +44,7 @@ var Lucifer = Meta{
type Bridge struct { type Bridge struct {
config *config.KnownBridge config *config.KnownBridge
Info *huego.Config Info *huego.Config
HueLights []*HueLight HueLights []*huego.Light
*huego.Bridge *huego.Bridge
*sync.RWMutex *sync.RWMutex
} }
@ -58,18 +58,22 @@ func (c *Bridge) Log() *zerolog.Logger {
} }
type HueLight struct { type HueLight struct {
huego.Light l huego.Light
controller *Bridge controller *Bridge
} }
func (hl *HueLight) Log() *zerolog.Logger { func (hl *HueLight) Log() *zerolog.Logger {
l := log.With(). l := log.With().
Int("caller", hl.ID). Int("caller", hl.l.ID).
Str("name", hl.Name). Str("name", hl.l.Name).
Bool("on", hl.IsOn()).Logger() Bool("on", hl.l.IsOn()).Logger()
return &l return &l
} }
func (hl *HueLight) GetPtr() (*huego.Light, error) {
return hl.controller.GetLight(hl.l.ID)
}
func getProxiedBridge(cridge *config.KnownBridge) *huego.Bridge { func getProxiedBridge(cridge *config.KnownBridge) *huego.Bridge {
cridge.Proxy = strings.TrimPrefix(cridge.Proxy, "socks5://") cridge.Proxy = strings.TrimPrefix(cridge.Proxy, "socks5://")
newTransport := http.DefaultTransport.(*http.Transport).Clone() newTransport := http.DefaultTransport.(*http.Transport).Clone()
@ -125,12 +129,12 @@ const (
Toggle Toggle
) )
type lCall func(light *HueLight) (checkFunc, error) type lCall func(light *huego.Light) (checkFunc, error)
type checkFunc func(light *HueLight) bool type checkFunc func(light *huego.Light) bool
var lightCallbacks = map[ToggleMode]lCall{ var lightCallbacks = map[ToggleMode]lCall{
ToggleOn: func(light *HueLight) (checkFunc, error) { ToggleOn: func(light *huego.Light) (checkFunc, error) {
return func(light *HueLight) bool { return func(light *huego.Light) bool {
light.State = &huego.State{ light.State = &huego.State{
On: true, On: true,
Bri: 100, Bri: 100,
@ -144,8 +148,8 @@ var lightCallbacks = map[ToggleMode]lCall{
}, },
light.On() light.On()
}, },
ToggleOff: func(light *HueLight) (checkFunc, error) { ToggleOff: func(light *huego.Light) (checkFunc, error) {
return func(light *HueLight) bool { return func(light *huego.Light) bool {
light.State = &huego.State{ light.State = &huego.State{
On: false, On: false,
Bri: 100, Bri: 100,
@ -159,8 +163,8 @@ var lightCallbacks = map[ToggleMode]lCall{
}, },
light.Off() light.Off()
}, },
/* ToggleDim: func(light *HueLight) (checkFunc, error) { /* ToggleDim: func(light *huego.Light) (checkFunc, error) {
return func(light *HueLight) bool { return func(light *huego.Light) bool {
if !light.IsOn() { if !light.IsOn() {
return false return false
} }
@ -168,8 +172,8 @@ var lightCallbacks = map[ToggleMode]lCall{
}, },
light.On() light.On()
},*/ },*/
ToggleRainbow: func(light *HueLight) (checkFunc, error) { ToggleRainbow: func(light *huego.Light) (checkFunc, error) {
return func(light *HueLight) bool { return func(light *huego.Light) bool {
if !light.IsOn() { if !light.IsOn() {
return false return false
} }
@ -179,12 +183,17 @@ var lightCallbacks = map[ToggleMode]lCall{
}, },
} }
func Assert(ctx context.Context, l *HueLight, mode ToggleMode) error { func Assert(ctx context.Context, l *huego.Light, mode ToggleMode) error {
act, ok := lightCallbacks[mode] act, ok := lightCallbacks[mode]
if !ok { if !ok {
panic("not implemented") panic("not implemented")
} }
/* l, err := lo.GetPtr()
if err != nil {
return err
}
*/
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -203,13 +212,13 @@ func Assert(ctx context.Context, l *HueLight, mode ToggleMode) error {
} }
} }
func toggle(l *HueLight, mode ToggleMode) error { func toggle(l *huego.Light, mode ToggleMode) error {
on := func(l *HueLight) error { on := func(l *huego.Light) error {
l.Log().Trace().Msg("turning light on...") log.Trace().Msg("turning light on...")
return l.On() return l.On()
} }
off := func(l *HueLight) error { off := func(l *huego.Light) error {
l.Log().Trace().Msg("turning light off...") log.Trace().Msg("turning light off...")
return l.Off() return l.Off()
} }
var err error var err error
@ -230,11 +239,11 @@ func toggle(l *HueLight, mode ToggleMode) error {
return err return err
} }
func ToggleLights(Lights []*HueLight, mode ToggleMode) { func ToggleLights(Lights []*huego.Light, mode ToggleMode) {
for _, l := range Lights { for _, l := range Lights {
err := toggle(l, mode) err := toggle(l, mode)
if err != nil { if err != nil {
l.Log().Error().Err(err).Bool("On", l.IsOn()).Msg("failed to toggle light") log.Error().Err(err).Bool("On", l.IsOn()).Msg("failed to toggle light")
} }
} }
} }
@ -250,19 +259,19 @@ func (c *Bridge) getLights() error {
c.Log().Info().Msgf("Found %d lights", len(l)) c.Log().Info().Msgf("Found %d lights", len(l))
for _, light := range l { for _, light := range l {
newlight := &HueLight{ newlight := &HueLight{
Light: light, l: light,
controller: c, controller: c,
} }
newlight.Log().Trace().Msg("+") log.Trace().Interface("new light", newlight.l).Msg("+")
c.HueLights = append(c.HueLights, newlight) c.HueLights = append(c.HueLights, &newlight.l)
Lucifer.Lock() Lucifer.Lock()
Lucifer.Lights[light.UniqueID] = newlight Lucifer.Lights[light.Name] = newlight
Lucifer.Unlock() Lucifer.Unlock()
} }
return nil return nil
} }
func (c *Bridge) Lights() []*HueLight { func (c *Bridge) Lights() []*huego.Light {
if len(c.HueLights) > 0 { if len(c.HueLights) > 0 {
return c.HueLights return c.HueLights
} }

@ -1,7 +1,51 @@
package ziggy package ziggy
import (
"fmt"
"github.com/amimof/huego"
)
// Multiplex is all of the lights (all of the lights). // Multiplex is all of the lights (all of the lights).
// I'll see myself out. // I'll see myself out.
type Multiplex struct { type Multiplex struct {
bridges []*Bridge bridges []*Bridge
} }
func GetGroupMap() (map[string]*huego.Group, error) {
var groupmap = make(map[string]*huego.Group)
for _, br := range Lucifer.Bridges {
gs, err := br.GetGroups()
if err != nil {
return nil, err
}
for i, g := range gs {
grp, gerr := br.GetGroup(i)
if gerr != nil {
log.Warn().Msgf("[%s] %w", g.Name, gerr)
continue
}
var count = 1
groupName := g.Name
for _, ok := groupmap[groupName]; ok; _, ok = groupmap[groupName] {
groupName = fmt.Sprintf("%s_%d", g.Name, count)
}
groupmap[groupName] = grp
}
}
return groupmap, nil
}
func GetLightMap() map[string]*huego.Light {
var lightMap = make(map[string]*huego.Light)
for _, l := range Lucifer.Lights {
realLight, err := l.GetPtr()
if err != nil {
l.Log().Warn().Err(err).Msg("failed to get light pointer")
continue
}
lightMap[realLight.Name] = realLight
}
return lightMap
}

@ -32,9 +32,9 @@ func init() {
func TurnAll(Known []*ziggy.Bridge, mode ziggy.ToggleMode) { func TurnAll(Known []*ziggy.Bridge, mode ziggy.ToggleMode) {
for _, bridge := range Known { for _, bridge := range Known {
for _, l := range bridge.HueLights { for _, l := range ziggy.GetLightMap() {
go func(l *ziggy.HueLight) { go func(l *huego.Light) {
l.Log().Debug(). log.Debug().
Str("caller", bridge.Host). Str("caller", bridge.Host).
Str("type", l.ProductName). Str("type", l.ProductName).
Bool("on", l.IsOn()).Msg(l.ModelID) Bool("on", l.IsOn()).Msg(l.ModelID)