Improve startup time, fiddle with completion
This commit is contained in:
parent
edfa970e26
commit
73a0e7b85a
@ -9,11 +9,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
tui "github.com/manifoldco/promptui"
|
tui "github.com/manifoldco/promptui"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
"github.com/google/shlex"
|
"github.com/google/shlex"
|
||||||
|
|
||||||
"git.tcp.direct/kayos/ziggs/internal/common"
|
"git.tcp.direct/kayos/ziggs/internal/common"
|
||||||
@ -74,14 +73,26 @@ func executor(cmd string) {
|
|||||||
levelsdebug := map[string]zerolog.Level{"info": zerolog.InfoLevel, "debug": zerolog.DebugLevel, "trace": zerolog.TraceLevel}
|
levelsdebug := map[string]zerolog.Level{"info": zerolog.InfoLevel, "debug": zerolog.DebugLevel, "trace": zerolog.TraceLevel}
|
||||||
debuglevels := map[zerolog.Level]string{zerolog.InfoLevel: "info", zerolog.DebugLevel: "debug", zerolog.TraceLevel: "trace"}
|
debuglevels := map[zerolog.Level]string{zerolog.InfoLevel: "info", zerolog.DebugLevel: "debug", zerolog.TraceLevel: "trace"}
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
println("current debug level: " + debuglevels[log.GetLevel()])
|
log.Info().Msgf("current debug level: %s", debuglevels[log.GetLevel()])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if newlevel, ok := levelsdebug[args[1]]; ok {
|
if newlevel, ok := levelsdebug[args[1]]; ok {
|
||||||
zerolog.SetGlobalLevel(newlevel)
|
zerolog.SetGlobalLevel(newlevel)
|
||||||
} else {
|
return
|
||||||
println("invalid argument: " + args[1])
|
|
||||||
}
|
}
|
||||||
|
if args[1] == "debugcli" || args[1] == "cli" {
|
||||||
|
if extraDebug {
|
||||||
|
extraDebug = false
|
||||||
|
log.Info().Msg("disabled cli debug")
|
||||||
|
} else {
|
||||||
|
extraDebug = true
|
||||||
|
log.Info().Msgf("dumping suggestions")
|
||||||
|
spew.Dump(suggestions)
|
||||||
|
log.Info().Msg("enabled cli debug")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
case "help":
|
case "help":
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
getHelp("")
|
getHelp("")
|
||||||
@ -90,13 +101,6 @@ func executor(cmd string) {
|
|||||||
getHelp(args[len(args)-1])
|
getHelp(args[len(args)-1])
|
||||||
case "clear":
|
case "clear":
|
||||||
print("\033[H\033[2J")
|
print("\033[H\033[2J")
|
||||||
case "debugcli":
|
|
||||||
if extraDebug {
|
|
||||||
extraDebug = false
|
|
||||||
} else {
|
|
||||||
extraDebug = true
|
|
||||||
}
|
|
||||||
spew.Dump(suggestions)
|
|
||||||
default:
|
default:
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return
|
return
|
||||||
@ -213,9 +217,12 @@ func saveHist() {
|
|||||||
func StartCLI() {
|
func StartCLI() {
|
||||||
log = config.GetLogger()
|
log = config.GetLogger()
|
||||||
processBridges()
|
processBridges()
|
||||||
grpmap := ziggy.GetGroupMap()
|
go func() {
|
||||||
processGroups(grpmap)
|
processGroups(ziggy.GetGroupMap())
|
||||||
processLights()
|
processLights(ziggy.GetLightMap())
|
||||||
|
processScenes(ziggy.GetSceneMap())
|
||||||
|
}()
|
||||||
|
buildTime, _ := common.Version()
|
||||||
prompt = cli.New(
|
prompt = cli.New(
|
||||||
executor,
|
executor,
|
||||||
completer,
|
completer,
|
||||||
@ -235,8 +242,7 @@ func StartCLI() {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("ziggs[%s] %s ", sel.String(), bulb), true
|
return fmt.Sprintf("ziggs[%s] %s ", sel.String(), bulb), true
|
||||||
}),
|
}),
|
||||||
cli.OptionTitle("ziggs"),
|
cli.OptionTitle("ziggs - built "+buildTime),
|
||||||
// cli.OptionCompletionOnDown(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
prompt.Run()
|
prompt.Run()
|
||||||
|
@ -2,8 +2,11 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/google/shlex"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -16,51 +19,71 @@ type completion struct {
|
|||||||
cli.Suggest
|
cli.Suggest
|
||||||
inner *ziggsCommand
|
inner *ziggsCommand
|
||||||
requires map[int]map[string]bool
|
requires map[int]map[string]bool
|
||||||
|
callback func([]string) bool
|
||||||
isAlias bool
|
isAlias bool
|
||||||
root bool
|
root bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c completion) qualifies(line string) bool {
|
func (c completion) qualifies(line string) bool {
|
||||||
args := strings.Fields(line)
|
args, err := shlex.Split(line)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("shlex.Split failed")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if len(args) <= 1 && c.root {
|
verbose := func(msg string, args ...interface{}) {
|
||||||
|
if !extraDebug {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Trace().Caller(1).
|
||||||
|
Int("len(args)", len(args)).
|
||||||
|
Int("len(c.requires)", len(c.requires)).Msgf(msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if extraDebug {
|
||||||
|
spew.Dump(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(args) <= 1 && c.root:
|
||||||
|
verbose("%v%s: len(args) <= 1 && c.root", grn, c.Text)
|
||||||
return true
|
return true
|
||||||
}
|
case len(args) < len(c.requires):
|
||||||
|
verbose(red + "len(args) < len(c.requires)" + rst)
|
||||||
if len(args) < len(c.requires) {
|
|
||||||
if extraDebug {
|
|
||||||
log.Trace().Int("len(args)", len(args)).Int("len(c.requires)", len(c.requires)).
|
|
||||||
Msg(red + "len(args) < len(c.requires)" + rst)
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
case len(args)-2 > len(c.requires):
|
||||||
if len(args)-2 > len(c.requires) {
|
verbose(red + "len(args)-2 > len(c.requires)" + rst)
|
||||||
if extraDebug {
|
|
||||||
log.Trace().Int("len(args)-2", len(args)-2).Int("len(c.requires)", len(c.requires)).
|
|
||||||
Msg(red + "len(args)-2 > len(c.requires)" + rst)
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
|
default:
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
var count = 0
|
var count = 0
|
||||||
for i, a := range args {
|
for i, a := range args {
|
||||||
i++
|
i++
|
||||||
if _, ok := c.requires[i][a]; ok {
|
if _, ok := c.requires[i][a]; ok {
|
||||||
if extraDebug {
|
verbose("%v%s: found %s (count++) %v", grn, c.Text, a, rst)
|
||||||
log.Trace().Msgf("%v%s: found %s%v", grn, c.Text, a, rst)
|
|
||||||
}
|
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if extraDebug && !(count >= len(c.requires)) {
|
ok := count >= len(c.requires)
|
||||||
log.Trace().Msgf("%v%s: count(%d) < len(c.requires)(%d)", red, c.Text, count, len(c.requires))
|
if !ok {
|
||||||
|
verbose("%v%s: count(%d) < len(c.requires)(%d)", red, c.Text, count, len(c.requires))
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return count >= len(c.requires)
|
if c.callback == nil {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var suggestions map[int]map[string]*completion
|
return c.callback(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
suggestions map[int]map[string]*completion
|
||||||
|
suggestionMutex = &sync.RWMutex{}
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Commands["ls"] = newZiggsCommand(cmdList, "list all lights, groups, scenes, rules, and schedules", 0)
|
Commands["ls"] = newZiggsCommand(cmdList, "list all lights, groups, scenes, rules, and schedules", 0)
|
||||||
@ -91,10 +114,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initCompletion() {
|
func initCompletion() {
|
||||||
|
suggestionMutex.Lock()
|
||||||
|
defer suggestionMutex.Unlock()
|
||||||
|
|
||||||
suggestions = make(map[int]map[string]*completion)
|
suggestions = make(map[int]map[string]*completion)
|
||||||
suggestions[0] = make(map[string]*completion)
|
suggestions[0] = make(map[string]*completion)
|
||||||
suggestions[1] = make(map[string]*completion)
|
suggestions[1] = make(map[string]*completion)
|
||||||
suggestions[2] = make(map[string]*completion)
|
suggestions[2] = make(map[string]*completion)
|
||||||
|
suggestions[3] = make(map[string]*completion)
|
||||||
|
suggestions[4] = make(map[string]*completion)
|
||||||
|
|
||||||
/* {Suggest: cli.Suggest{Text: "lights"}, inner: Commands["lights"]},
|
/* {Suggest: cli.Suggest{Text: "lights"}, inner: Commands["lights"]},
|
||||||
{Suggest: cli.Suggest{Text: "groups"}, inner: Commands["groups"]},
|
{Suggest: cli.Suggest{Text: "groups"}, inner: Commands["groups"]},
|
||||||
@ -111,7 +139,6 @@ func initCompletion() {
|
|||||||
{Suggest: cli.Suggest{Text: "dump"}, inner: Commands["dump"]},
|
{Suggest: cli.Suggest{Text: "dump"}, inner: Commands["dump"]},
|
||||||
{Suggest: cli.Suggest{Text: "load"}, inner: Commands["load"]},
|
{Suggest: cli.Suggest{Text: "load"}, inner: Commands["load"]},
|
||||||
{Suggest: cli.Suggest{Text: "use", Description: "select bridge to perform actions on"}},
|
{Suggest: cli.Suggest{Text: "use", Description: "select bridge to perform actions on"}},
|
||||||
|
|
||||||
{Suggest: cli.Suggest{Text: "exit", Description: "exit ziggs"}},
|
{Suggest: cli.Suggest{Text: "exit", Description: "exit ziggs"}},
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -156,16 +183,13 @@ func initCompletion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func completer(in cli.Document) []cli.Suggest {
|
func completer(in cli.Document) []cli.Suggest {
|
||||||
c := in.CurrentLine()
|
c := in.Text
|
||||||
|
|
||||||
infields := strings.Fields(c)
|
infields, _ := shlex.Split(c)
|
||||||
var head = len(infields) - 1
|
var head = len(infields) - 1
|
||||||
if head < 0 {
|
if head < 0 {
|
||||||
head = 0
|
head = 0
|
||||||
}
|
}
|
||||||
if head == 1 {
|
|
||||||
head = 1
|
|
||||||
}
|
|
||||||
if head > 0 && in.LastKeyStroke() == ' ' {
|
if head > 0 && in.LastKeyStroke() == ' ' {
|
||||||
head++
|
head++
|
||||||
}
|
}
|
||||||
@ -174,11 +198,15 @@ func completer(in cli.Document) []cli.Suggest {
|
|||||||
log.Trace().Int("head", head).Msgf("completing %v", infields)
|
log.Trace().Int("head", head).Msgf("completing %v", infields)
|
||||||
}
|
}
|
||||||
var sugs []cli.Suggest
|
var sugs []cli.Suggest
|
||||||
|
suggestionMutex.RLock()
|
||||||
|
defer suggestionMutex.RUnlock()
|
||||||
for _, sug := range suggestions[head] {
|
for _, sug := range suggestions[head] {
|
||||||
if sug.qualifies(c) {
|
if !sug.qualifies(c) {
|
||||||
if in.GetWordBeforeCursor() != "" && strings.HasPrefix(sug.Text, in.GetWordBeforeCursor()) {
|
continue
|
||||||
sugs = append(sugs, sug.Suggest)
|
|
||||||
}
|
}
|
||||||
|
if in.TextBeforeCursor() != "" && strings.Contains(strings.ToLower(sug.Text),
|
||||||
|
strings.ToLower(strings.TrimSpace(in.GetWordBeforeCursorWithSpace()))) {
|
||||||
|
sugs = append(sugs, sug.Suggest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sugs
|
return sugs
|
||||||
|
@ -21,7 +21,7 @@ func cmdGet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
groupMap map[string]*huego.Group
|
groupMap map[string]*ziggy.HueGroup
|
||||||
lightMap map[string]*ziggy.HueLight
|
lightMap map[string]*ziggy.HueLight
|
||||||
currentState *huego.State
|
currentState *huego.State
|
||||||
argHead = -1
|
argHead = -1
|
||||||
|
@ -10,6 +10,9 @@ import (
|
|||||||
var tabber = tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', tabwriter.AlignRight)
|
var tabber = tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', tabwriter.AlignRight)
|
||||||
|
|
||||||
func getHelp(target string) {
|
func getHelp(target string) {
|
||||||
|
suggestionMutex.RLock()
|
||||||
|
defer suggestionMutex.RUnlock()
|
||||||
|
|
||||||
if target != "" && target != "meta" {
|
if target != "" && target != "meta" {
|
||||||
for _, su := range suggestions[0] {
|
for _, su := range suggestions[0] {
|
||||||
if strings.Contains(strings.ToLower(su.Text), strings.ToLower(target)) {
|
if strings.Contains(strings.ToLower(su.Text), strings.ToLower(target)) {
|
||||||
|
@ -2,38 +2,88 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||||
"github.com/amimof/huego"
|
|
||||||
|
|
||||||
"git.tcp.direct/kayos/ziggs/internal/ziggy"
|
"git.tcp.direct/kayos/ziggs/internal/ziggy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func processGroups(grps map[string]*huego.Group) {
|
func processGroups(grps map[string]*ziggy.HueGroup) {
|
||||||
for grp, g := range grps {
|
for grp, g := range grps {
|
||||||
suffix := ""
|
suffix := ""
|
||||||
if g.Type != "" {
|
if g.Type != "" {
|
||||||
suffix = " (" + g.Type + ")"
|
suffix = " (" + g.Type + ")"
|
||||||
}
|
}
|
||||||
|
suggestionMutex.Lock()
|
||||||
suggestions[2][grp] = &completion{
|
suggestions[2][grp] = &completion{
|
||||||
Suggest: cli.Suggest{
|
Suggest: cli.Suggest{
|
||||||
Text: grp,
|
Text: grp,
|
||||||
Description: "Group" + suffix,
|
Description: "Group" + suffix,
|
||||||
},
|
},
|
||||||
requires: map[int]map[string]bool{
|
requires: map[int]map[string]bool{
|
||||||
1: {"set": true, "s": true, "delete": true, "d": true},
|
1: {"set": true, "s": true, "delete": true, "d": true, "get": true, "dump": true},
|
||||||
2: {"group": true, "g": true},
|
2: {"group": true, "g": true},
|
||||||
},
|
},
|
||||||
root: false,
|
root: false,
|
||||||
}
|
}
|
||||||
|
suggestionMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processLights() {
|
func processScenes(scns map[string]*ziggy.HueScene) {
|
||||||
for lt, l := range ziggy.GetLightMap() {
|
for scn, s := range scns {
|
||||||
|
suffix := ""
|
||||||
|
if s.Type != "" {
|
||||||
|
suffix = " (" + s.Type + ")"
|
||||||
|
}
|
||||||
|
suggestionMutex.Lock()
|
||||||
|
suggestions[4][scn] = &completion{
|
||||||
|
Suggest: cli.Suggest{
|
||||||
|
Text: scn,
|
||||||
|
Description: "Scene" + suffix,
|
||||||
|
},
|
||||||
|
requires: map[int]map[string]bool{
|
||||||
|
1: {"set": true, "s": true, "delete": true, "d": true, "get": true, "dump": true},
|
||||||
|
2: {"group": true, "g": true, "scene": true, "s": true, "light": true, "l": true},
|
||||||
|
4: {"scene": true, "s": true},
|
||||||
|
},
|
||||||
|
callback: func(args []string) bool {
|
||||||
|
if extraDebug {
|
||||||
|
log.Trace().Msgf("Checking if scene %s belongs to group %s, their group is %s",
|
||||||
|
s.Name, args[3], s.Group)
|
||||||
|
}
|
||||||
|
if len(args) < 4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
delGetDumpOnly := args[1] == "scene" || args[1] == "s"
|
||||||
|
switch {
|
||||||
|
case delGetDumpOnly && args[3] == "scene" || args[3] == "s":
|
||||||
|
return false
|
||||||
|
case delGetDumpOnly && args[0] == "set":
|
||||||
|
return false
|
||||||
|
case args[1] == "group" || args[1] == "g":
|
||||||
|
if extraDebug {
|
||||||
|
log.Trace().Msgf("Checking if group %s is %s", args[3], s.Group)
|
||||||
|
}
|
||||||
|
if args[3] == s.Group {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
root: false,
|
||||||
|
}
|
||||||
|
suggestionMutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func processLights(lghts map[string]*ziggy.HueLight) {
|
||||||
|
for lt, l := range lghts {
|
||||||
suffix := ""
|
suffix := ""
|
||||||
if l.Type != "" {
|
if l.Type != "" {
|
||||||
suffix = " (" + l.Type + ")"
|
suffix = " (" + l.Type + ")"
|
||||||
}
|
}
|
||||||
|
suggestionMutex.Lock()
|
||||||
suggestions[2][lt] = &completion{
|
suggestions[2][lt] = &completion{
|
||||||
Suggest: cli.Suggest{
|
Suggest: cli.Suggest{
|
||||||
Text: lt,
|
Text: lt,
|
||||||
@ -45,11 +95,13 @@ func processLights() {
|
|||||||
},
|
},
|
||||||
root: false,
|
root: false,
|
||||||
}
|
}
|
||||||
|
suggestionMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processBridges() {
|
func processBridges() {
|
||||||
for brd, b := range ziggy.Lucifer.Bridges {
|
for brd, b := range ziggy.Lucifer.Bridges {
|
||||||
|
suggestionMutex.Lock()
|
||||||
suggestions[1]["bridge"] = &completion{
|
suggestions[1]["bridge"] = &completion{
|
||||||
Suggest: cli.Suggest{
|
Suggest: cli.Suggest{
|
||||||
Text: brd,
|
Text: brd,
|
||||||
@ -58,5 +110,6 @@ func processBridges() {
|
|||||||
requires: map[int]map[string]bool{0: {"use": true, "u": true}},
|
requires: map[int]map[string]bool{0: {"use": true, "u": true}},
|
||||||
root: false,
|
root: false,
|
||||||
}
|
}
|
||||||
|
suggestionMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,11 @@ type cmdTarget interface {
|
|||||||
Effect(string) error
|
Effect(string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrNotEnoughArguments = errors.New("not enough arguments")
|
||||||
|
|
||||||
func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||||
if len(args) < 3 {
|
if len(args) < 3 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -37,7 +39,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
groupMap map[string]*huego.Group
|
groupMap map[string]*ziggy.HueGroup
|
||||||
lightMap map[string]*ziggy.HueLight
|
lightMap map[string]*ziggy.HueLight
|
||||||
actions []action
|
actions []action
|
||||||
currentState *huego.State
|
currentState *huego.State
|
||||||
@ -141,7 +143,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
})
|
})
|
||||||
case "hue", "h":
|
case "hue", "h":
|
||||||
if len(args) == argHead-1 {
|
if len(args) == argHead-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
argHead++
|
argHead++
|
||||||
newHue, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
newHue, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
||||||
@ -157,7 +159,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
})
|
})
|
||||||
case "saturation", "sat":
|
case "saturation", "sat":
|
||||||
if len(args) == argHead-1 {
|
if len(args) == argHead-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
argHead++
|
argHead++
|
||||||
newSat, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
newSat, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
||||||
@ -173,7 +175,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
})
|
})
|
||||||
case "effect", "e":
|
case "effect", "e":
|
||||||
if len(args) == argHead-1 {
|
if len(args) == argHead-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
argHead++
|
argHead++
|
||||||
newEffect := strings.TrimSpace(args[argHead])
|
newEffect := strings.TrimSpace(args[argHead])
|
||||||
@ -186,7 +188,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
})
|
})
|
||||||
case "temperature", "temp":
|
case "temperature", "temp":
|
||||||
if len(args) == argHead-1 {
|
if len(args) == argHead-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
argHead++
|
argHead++
|
||||||
newTemp, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
newTemp, numErr := strconv.Atoi(strings.TrimSpace(args[argHead]))
|
||||||
@ -222,11 +224,11 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
case "scene", "sc":
|
case "scene", "sc":
|
||||||
if len(args) == argHead-1 {
|
if len(args) == argHead-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
argHead++
|
argHead++
|
||||||
if argHead > len(args)-1 {
|
if argHead > len(args)-1 {
|
||||||
return errors.New("not enough arguments")
|
return ErrNotEnoughArguments
|
||||||
}
|
}
|
||||||
targetScene := strings.TrimSpace(args[argHead])
|
targetScene := strings.TrimSpace(args[argHead])
|
||||||
actions = append(actions, func() error {
|
actions = append(actions, func() error {
|
||||||
@ -251,7 +253,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||||||
if target == nil {
|
if target == nil {
|
||||||
return errors.New("no target specified")
|
return errors.New("no target specified")
|
||||||
}
|
}
|
||||||
tg, tgok := target.(*huego.Group)
|
tg, tgok := target.(*ziggy.HueGroup)
|
||||||
tl, tlok := target.(*ziggy.HueLight)
|
tl, tlok := target.(*ziggy.HueLight)
|
||||||
switch {
|
switch {
|
||||||
case tgok:
|
case tgok:
|
||||||
|
@ -63,6 +63,18 @@ type HueLight struct {
|
|||||||
controller *Bridge
|
controller *Bridge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HueGroup struct {
|
||||||
|
*huego.Group
|
||||||
|
scenes map[string]*HueScene
|
||||||
|
controller *Bridge
|
||||||
|
}
|
||||||
|
|
||||||
|
type HueScene struct {
|
||||||
|
*huego.Scene
|
||||||
|
controller *Bridge
|
||||||
|
group *HueGroup
|
||||||
|
}
|
||||||
|
|
||||||
func (hl *HueLight) Scene(s string) error {
|
func (hl *HueLight) Scene(s string) error {
|
||||||
return hl.Scene(s)
|
return hl.Scene(s)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ziggy
|
package ziggy
|
||||||
|
|
||||||
import "github.com/amimof/huego"
|
import "strconv"
|
||||||
|
|
||||||
// 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.
|
||||||
@ -32,8 +32,8 @@ func GetLightMap() map[string]*HueLight {
|
|||||||
return lightMap
|
return lightMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGroupMap() map[string]*huego.Group {
|
func GetGroupMap() map[string]*HueGroup {
|
||||||
var groupMap = make(map[string]*huego.Group)
|
var groupMap = make(map[string]*HueGroup)
|
||||||
for _, c := range Lucifer.Bridges {
|
for _, c := range Lucifer.Bridges {
|
||||||
gs, err := c.GetGroups()
|
gs, err := c.GetGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -50,14 +50,16 @@ func GetGroupMap() map[string]*huego.Group {
|
|||||||
log.Warn().Msgf("duplicate group name %s on bridge %s - please rename", g.Name, c.ID)
|
log.Warn().Msgf("duplicate group name %s on bridge %s - please rename", g.Name, c.ID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
groupMap[g.Name] = group
|
hg := &HueGroup{Group: group, controller: c}
|
||||||
|
groupMap[g.Name] = hg
|
||||||
|
groupMap[strconv.Itoa(g.ID)] = hg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return groupMap
|
return groupMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSceneMap() map[string]*huego.Scene {
|
func GetSceneMap() map[string]*HueScene {
|
||||||
var sceneMap = make(map[string]*huego.Scene)
|
var sceneMap = make(map[string]*HueScene)
|
||||||
for _, c := range Lucifer.Bridges {
|
for _, c := range Lucifer.Bridges {
|
||||||
scs, err := c.GetScenes()
|
scs, err := c.GetScenes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,11 +72,14 @@ func GetSceneMap() map[string]*huego.Scene {
|
|||||||
log.Warn().Msgf("failed to get pointer for scene %s on bridge %s: %v", s.Name, c.ID, gerr)
|
log.Warn().Msgf("failed to get pointer for scene %s on bridge %s: %v", s.Name, c.ID, gerr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := sceneMap[s.Name]; ok {
|
if _, ok := sceneMap[s.Name]; !ok {
|
||||||
|
sceneMap[s.Name] = &HueScene{Scene: group, controller: c}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := sceneMap[s.Name+"-2"]; ok {
|
||||||
log.Warn().Msgf("duplicate scene name %s on bridge %s - please rename", s.Name, c.ID)
|
log.Warn().Msgf("duplicate scene name %s on bridge %s - please rename", s.Name, c.ID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sceneMap[s.Name] = group
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sceneMap
|
return sceneMap
|
||||||
|
@ -23,7 +23,7 @@ func (c *Bridge) FindLight(input string) (light *HueLight, err error) {
|
|||||||
return &HueLight{Light: l, controller: c}, nil
|
return &HueLight{Light: l, controller: c}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Bridge) FindGroup(input string) (light *huego.Group, err error) {
|
func (c *Bridge) FindGroup(input string) (light *HueGroup, err error) {
|
||||||
var groupID int
|
var groupID int
|
||||||
if groupID, err = strconv.Atoi(input); err != nil {
|
if groupID, err = strconv.Atoi(input); err != nil {
|
||||||
targ, ok := GetGroupMap()[input]
|
targ, ok := GetGroupMap()[input]
|
||||||
@ -32,5 +32,34 @@ func (c *Bridge) FindGroup(input string) (light *huego.Group, err error) {
|
|||||||
}
|
}
|
||||||
return targ, nil
|
return targ, nil
|
||||||
}
|
}
|
||||||
return c.GetGroup(groupID)
|
var hg *huego.Group
|
||||||
|
if hg, err = c.GetGroup(groupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HueGroup{Group: hg, controller: c}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hg *HueGroup) Scenes() ([]*HueScene, error) {
|
||||||
|
scenes, err := hg.controller.GetScenes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var ret []*HueScene
|
||||||
|
for _, s := range scenes {
|
||||||
|
intID, err := strconv.Atoi(s.Group)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Msgf("unable to parse group ID from scene %s: %v", s.Name, err)
|
||||||
|
}
|
||||||
|
if intID != hg.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s, err := hg.controller.GetScene(s.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Msgf("unable to get scene pointer for scene %s: %v", s.Name, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret = append(ret, &HueScene{Scene: s, controller: hg.controller})
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user