literally had to make these changes before I could turn my hallway light back on :^)
This commit is contained in:
parent
eeea125396
commit
7a33b30802
@ -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
|
||||||
|
}
|
||||||
|
6
main.go
6
main.go
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user