Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
7aef6194d1 | |||
eb95d06a1b |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ assets/
|
||||
*.unused
|
||||
*.toml
|
||||
*.swp
|
||||
*.save
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||
@ -18,7 +19,10 @@ import (
|
||||
"git.tcp.direct/kayos/ziggs/internal/ziggy"
|
||||
)
|
||||
|
||||
var log *zerolog.Logger
|
||||
var (
|
||||
log *zerolog.Logger
|
||||
prompt *cli.Prompt
|
||||
)
|
||||
|
||||
func validate(input string) error {
|
||||
if len(strings.TrimSpace(input)) < 1 {
|
||||
@ -27,6 +31,59 @@ func validate(input string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Selection struct {
|
||||
Bridge string
|
||||
Action string
|
||||
Target struct {
|
||||
Type string
|
||||
Name string
|
||||
}
|
||||
}
|
||||
|
||||
type pool struct {
|
||||
p *sync.Pool
|
||||
}
|
||||
|
||||
var stringers = pool{p: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &strings.Builder{}
|
||||
}}}
|
||||
|
||||
func (p *pool) Get() *strings.Builder {
|
||||
return p.p.Get().(*strings.Builder)
|
||||
}
|
||||
|
||||
func (p *pool) Put(sb *strings.Builder) {
|
||||
sb.Reset()
|
||||
p.p.Put(sb)
|
||||
}
|
||||
|
||||
func (s *Selection) String() string {
|
||||
if s.Bridge == "" && s.Action == "" {
|
||||
return "~"
|
||||
}
|
||||
builder := stringers.Get()
|
||||
builder.WriteString(s.Bridge)
|
||||
if s.Action != "" {
|
||||
builder.WriteString("/")
|
||||
builder.WriteString(s.Action)
|
||||
}
|
||||
if s.Target.Type != "" {
|
||||
builder.WriteString("/")
|
||||
builder.WriteString(s.Target.Type)
|
||||
builder.WriteString("s")
|
||||
}
|
||||
if s.Target.Name != "" {
|
||||
builder.WriteString("/")
|
||||
builder.WriteString(s.Target.Name)
|
||||
}
|
||||
res := builder.String()
|
||||
stringers.Put(builder)
|
||||
return res
|
||||
}
|
||||
|
||||
var sel = &Selection{}
|
||||
|
||||
func InteractiveAuth() string {
|
||||
passPrompt := tui.Prompt{
|
||||
Label: "API Key (AKA user)",
|
||||
@ -56,6 +113,9 @@ func executor(cmd string) {
|
||||
case "quit", "exit":
|
||||
os.Exit(0)
|
||||
case "use":
|
||||
if len(ziggy.Lucifer.Bridges) < 2 {
|
||||
return
|
||||
}
|
||||
if len(args) < 2 {
|
||||
println("use: use <bridge>")
|
||||
return
|
||||
@ -63,8 +123,8 @@ func executor(cmd string) {
|
||||
if br, ok := ziggy.Lucifer.Bridges[args[1]]; !ok {
|
||||
println("invalid bridge: " + args[1])
|
||||
} else {
|
||||
selectedBridge = args[1]
|
||||
log.Info().Str("host", br.Host).Int("lights", len(br.HueLights)).Msg("switched to bridge: " + selectedBridge)
|
||||
sel.Bridge = args[1]
|
||||
log.Info().Str("host", br.Host).Int("lights", len(br.HueLights)).Msg("switched to bridge: " + sel.Bridge)
|
||||
}
|
||||
case "debug":
|
||||
levelsdebug := map[string]zerolog.Level{"info": zerolog.InfoLevel, "debug": zerolog.DebugLevel, "trace": zerolog.TraceLevel}
|
||||
@ -93,14 +153,14 @@ func executor(cmd string) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
br, ok := ziggy.Lucifer.Bridges[selectedBridge]
|
||||
if selectedBridge == "" || !ok {
|
||||
prompt := tui.Select{
|
||||
br, ok := ziggy.Lucifer.Bridges[sel.Bridge]
|
||||
if sel.Bridge == "" || !ok {
|
||||
q := tui.Select{
|
||||
Label: "Send to all known bridges?",
|
||||
Items: []string{"yes", "no"},
|
||||
Pointer: common.ZiggsPointer,
|
||||
}
|
||||
_, ch, _ := prompt.Run()
|
||||
_, ch, _ := q.Run()
|
||||
if ch != "yes" {
|
||||
return
|
||||
}
|
||||
@ -182,8 +242,6 @@ loop:
|
||||
return nil
|
||||
}
|
||||
|
||||
var selectedBridge = ""
|
||||
|
||||
const bulb = ``
|
||||
|
||||
func getHist() []string {
|
||||
@ -192,17 +250,14 @@ func getHist() []string {
|
||||
|
||||
func StartCLI() {
|
||||
log = config.GetLogger()
|
||||
processBridges(ziggy.Lucifer.Bridges)
|
||||
for _, br := range ziggy.Lucifer.Bridges {
|
||||
grpmap, err := getGroupMap(br)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("error getting group map")
|
||||
} else {
|
||||
processGroups(br, grpmap)
|
||||
}
|
||||
processBridges()
|
||||
grpmap, err := getGroupMap()
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("error getting group map")
|
||||
}
|
||||
|
||||
p := cli.New(
|
||||
processGroups(grpmap)
|
||||
processLights()
|
||||
prompt = cli.New(
|
||||
executor,
|
||||
completer,
|
||||
// cli.OptionPrefixBackgroundColor(cli.Black),
|
||||
@ -214,15 +269,16 @@ func StartCLI() {
|
||||
cli.OptionSelectedSuggestionTextColor(cli.Green),
|
||||
cli.OptionLivePrefix(
|
||||
func() (prefix string, useLivePrefix bool) {
|
||||
sel := "~"
|
||||
if len(ziggy.Lucifer.Bridges) > 1 && selectedBridge != "" {
|
||||
sel = selectedBridge
|
||||
if len(ziggy.Lucifer.Bridges) == 1 {
|
||||
for brid, _ := range ziggy.Lucifer.Bridges {
|
||||
sel.Bridge = brid
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("ziggs[%s] %s ", sel, bulb), true
|
||||
return fmt.Sprintf("ziggs[%s] %s ", sel.String(), bulb), true
|
||||
}),
|
||||
cli.OptionTitle("ziggs"),
|
||||
cli.OptionCompletionOnDown(),
|
||||
)
|
||||
|
||||
p.Run()
|
||||
prompt.Run()
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||
"github.com/amimof/huego"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"git.tcp.direct/kayos/ziggs/internal/system"
|
||||
"git.tcp.direct/kayos/ziggs/internal/ziggy"
|
||||
@ -23,10 +23,6 @@ var (
|
||||
cpuCancel context.CancelFunc
|
||||
)
|
||||
|
||||
func init() {
|
||||
cpuCtx, cpuCancel = context.WithCancel(context.Background())
|
||||
}
|
||||
|
||||
func ParseHexColorFast(s string) (c color.RGBA, err error) {
|
||||
c.A = 0xff
|
||||
|
||||
@ -74,30 +70,35 @@ func cmdLights(br *ziggy.Bridge, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type cmdTarget interface {
|
||||
On() error
|
||||
Off() error
|
||||
Bri(uint8) error
|
||||
Ct(uint16) error
|
||||
Hue(uint16) error
|
||||
Sat(uint8) error
|
||||
Col(color.Color) error
|
||||
SetState(huego.State) error
|
||||
Alert(string) error
|
||||
}
|
||||
|
||||
func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
if len(args) < 3 {
|
||||
return errors.New("not enough arguments")
|
||||
}
|
||||
|
||||
var target interface {
|
||||
On() error
|
||||
Off() error
|
||||
Bri(uint8) error
|
||||
Ct(uint16) error
|
||||
Hue(uint16) error
|
||||
Sat(uint8) error
|
||||
Col(color.Color) error
|
||||
SetState(huego.State) error
|
||||
Alert(string) error
|
||||
}
|
||||
type (
|
||||
action func() error
|
||||
)
|
||||
|
||||
var groupmap map[string]*huego.Group
|
||||
var (
|
||||
groupmap map[string]*huego.Group
|
||||
actions []action
|
||||
currentState *huego.State
|
||||
argHead = -1
|
||||
target cmdTarget
|
||||
)
|
||||
|
||||
type action func() error
|
||||
var actions []action
|
||||
var currentState *huego.State
|
||||
|
||||
var argHead = -1
|
||||
for range args {
|
||||
argHead++
|
||||
if len(args) <= argHead {
|
||||
@ -107,7 +108,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
switch args[argHead] {
|
||||
case "group", "g", "grp":
|
||||
var err error
|
||||
groupmap, err = getGroupMap(bridge)
|
||||
groupmap, err = getGroupMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -119,6 +120,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
if !ok {
|
||||
return errors.New("group not found")
|
||||
}
|
||||
|
||||
target = g
|
||||
case "on":
|
||||
actions = append(actions, target.On)
|
||||
@ -189,34 +191,32 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
case "cpu":
|
||||
switch cpuOn {
|
||||
case false:
|
||||
cpuCtx, cpuCancel = context.WithCancel(context.Background())
|
||||
load, err := system.CPULoadGradient(cpuCtx,
|
||||
"deepskyblue", "seagreen", "darkorchid", "gold", "deeppink")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info().Msg("turning CPU load lights on")
|
||||
go func() {
|
||||
log.Info().Msg("turning CPU load lights on for ")
|
||||
go func(cpuTarget cmdTarget) {
|
||||
cpuOn = true
|
||||
defer func() {
|
||||
cpuOn = false
|
||||
}()
|
||||
cpuTarget := target
|
||||
for {
|
||||
select {
|
||||
case <-cpuCtx.Done():
|
||||
cpuOn = false
|
||||
return
|
||||
default:
|
||||
time.Sleep(2 * time.Second)
|
||||
clr := <-load
|
||||
case clr := <-load:
|
||||
log.Trace().Msgf("CPU load color: %v", clr.Hex())
|
||||
cHex, cErr := ParseHexColorFast(clr.Hex())
|
||||
if cErr != nil {
|
||||
log.Error().Err(cErr).Msg("failed to parse color")
|
||||
continue
|
||||
}
|
||||
|
||||
colErr := cpuTarget.Col(cHex)
|
||||
_ = cpuTarget.Bri(100)
|
||||
if colErr != nil {
|
||||
log.Error().Err(colErr).Msg("failed to set color")
|
||||
time.Sleep(3 * time.Second)
|
||||
@ -224,7 +224,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}(target)
|
||||
return nil
|
||||
case true:
|
||||
log.Info().Msg("turning CPU load lights off")
|
||||
@ -241,13 +241,15 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
if target == nil {
|
||||
return errors.New("no target specified")
|
||||
}
|
||||
tg, tgok := target.(*huego.Group)
|
||||
tl, tlok := target.(*huego.Light)
|
||||
tgroup, tgok := target.(*huego.Group)
|
||||
tlight, tlok := target.(*huego.Light)
|
||||
switch {
|
||||
case tgok:
|
||||
currentState = tg.State
|
||||
currentState = tgroup.State
|
||||
case tlok:
|
||||
currentState = tl.State
|
||||
currentState = tlight.State
|
||||
default:
|
||||
return errors.New("unknown target")
|
||||
}
|
||||
log.Trace().Msgf("current state: %v", currentState)
|
||||
for d, act := range actions {
|
||||
@ -258,84 +260,61 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
||||
}
|
||||
switch {
|
||||
case tgok:
|
||||
currentState = tg.State
|
||||
currentState = tgroup.State
|
||||
case tlok:
|
||||
currentState = tl.State
|
||||
currentState = tlight.State
|
||||
}
|
||||
log.Trace().Msgf("new state: %v", currentState)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getGroupMap(br *ziggy.Bridge) (map[string]*huego.Group, error) {
|
||||
func getGroupMap() (map[string]*huego.Group, error) {
|
||||
var groupmap = make(map[string]*huego.Group)
|
||||
gs, err := br.Bridge.GetGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, g := range gs {
|
||||
groupmap[g.Name] = &g
|
||||
for _, br := range ziggy.Lucifer.Bridges {
|
||||
groups, err := br.GetGroups()
|
||||
log.Trace().Msgf(spew.Sprint(groups))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, group := range groups {
|
||||
groupName := group.Name
|
||||
var count = 1
|
||||
for _, ok := groupmap[groupName]; ok; _, ok = groupmap[groupName] {
|
||||
groupName = fmt.Sprintf("%s_%d", group.Name, count)
|
||||
}
|
||||
groupmap[groupName] = &group
|
||||
}
|
||||
}
|
||||
return groupmap, nil
|
||||
}
|
||||
|
||||
func getLightMap(br *ziggy.Bridge) (map[string]*huego.Light, error) {
|
||||
var lightmap = make(map[string]*huego.Light)
|
||||
ls, err := br.Bridge.GetLights()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, l := range ls {
|
||||
lightmap[l.Name] = &l
|
||||
}
|
||||
return lightmap, nil
|
||||
}
|
||||
|
||||
func cmdGroups(br *ziggy.Bridge, args []string) error {
|
||||
groupmap, err := getGroupMap(br)
|
||||
groupmap, err := getGroupMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(groupmap) == 0 {
|
||||
return errors.New("no groups found")
|
||||
}
|
||||
for _, g := range groupmap {
|
||||
log.Info().Str("caller", g.Name).Str("type", g.Type).Int("ID", g.ID).
|
||||
Str("class", g.Class).Bool("on", g.IsOn()).Msgf("%v", g.GroupState)
|
||||
for n, g := range groupmap {
|
||||
if n != g.Name {
|
||||
log.Warn().Msgf("group name mismatch: %s != %s", n, g.Name)
|
||||
}
|
||||
slog := log.With().Str("caller", g.Name).Int("ID", g.ID).Logger()
|
||||
slog.Info().Msgf("\n\tType: %v\n\tClass: %v\n\t%v", g.Type, g.Class, spew.Sprint(g.State))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type reactor func(bridge *ziggy.Bridge, args []string) error
|
||||
|
||||
var bridgeCMD = map[string]reactor{
|
||||
"scan": cmdScan,
|
||||
"lights": cmdLights,
|
||||
"groups": cmdGroups,
|
||||
"set": cmdSet,
|
||||
}
|
||||
|
||||
type completeMapper map[*cli.Suggest][]cli.Suggest
|
||||
|
||||
var suggestions completeMapper = make(map[*cli.Suggest][]cli.Suggest)
|
||||
|
||||
func processGroups(br *ziggy.Bridge, grps map[string]*huego.Group) {
|
||||
set := &cli.Suggest{
|
||||
Text: "set",
|
||||
}
|
||||
suggestions[set] = []cli.Suggest{
|
||||
{Text: "light"},
|
||||
}
|
||||
|
||||
/* for grp, g := range grps {
|
||||
suggestions[set] = append(
|
||||
suggestions[set],
|
||||
cli.Suggest{
|
||||
Text: grp,
|
||||
Description: br.ID + ": " + g.Type,
|
||||
})
|
||||
}*/
|
||||
}
|
||||
|
||||
func processBridges(brs map[string]*ziggy.Bridge) {
|
||||
for brd, c := range brs {
|
||||
use := cli.Suggest{
|
||||
Text: "use",
|
||||
Description: "select bridge to perform actions on",
|
||||
}
|
||||
suggestions[&use] = append(
|
||||
suggestions[&use],
|
||||
cli.Suggest{
|
||||
Text: brd,
|
||||
Description: c.Host,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,172 @@
|
||||
package interactive
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
cli "git.tcp.direct/Mirrors/go-prompt"
|
||||
"github.com/amimof/huego"
|
||||
|
||||
"git.tcp.direct/kayos/ziggs/internal/ziggy"
|
||||
)
|
||||
|
||||
type reactor func(bridge *ziggy.Bridge, args []string) error
|
||||
|
||||
const (
|
||||
grn = "\033[32m"
|
||||
red = "\033[31m"
|
||||
ylw = "\033[33m"
|
||||
rst = "\033[0m"
|
||||
)
|
||||
|
||||
var bridgeCMD = map[string]reactor{
|
||||
"scan": cmdScan,
|
||||
"lights": cmdLights,
|
||||
"groups": cmdGroups,
|
||||
"set": cmdSet,
|
||||
}
|
||||
|
||||
type completion struct {
|
||||
cli.Suggest
|
||||
requires map[int][]string
|
||||
root bool
|
||||
}
|
||||
|
||||
func (c completion) qualifies(line string) bool {
|
||||
args := strings.Fields(line)
|
||||
|
||||
if c.root && len(args) < 1 {
|
||||
return true
|
||||
}
|
||||
/*if c.root && len(args) > 0 {
|
||||
return false
|
||||
}*/
|
||||
if len(args) < len(c.requires) {
|
||||
log.Trace().Int("len(args)", len(args)).Int("len(c.requires)", len(c.requires)).
|
||||
Msg(red + "len(args) < len(c.requires)" + rst)
|
||||
return false
|
||||
}
|
||||
if len(args)-2 > len(c.requires) {
|
||||
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
|
||||
}
|
||||
has := func(b []string, a string) bool {
|
||||
for _, r := range b {
|
||||
if a == r {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
var count = 0
|
||||
for i, a := range args {
|
||||
if has(c.requires[i], a) {
|
||||
log.Trace().Msgf("%v%s: found %s%v", grn, c.Text, a, rst)
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == len(c.requires) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var suggestions map[int][]completion
|
||||
|
||||
func init() {
|
||||
suggestions = make(map[int][]completion)
|
||||
suggestions[0] = []completion{
|
||||
{Suggest: cli.Suggest{Text: "lights", Description: "print all known lights"}},
|
||||
{Suggest: cli.Suggest{Text: "groups", Description: "print all known groups"}},
|
||||
{Suggest: cli.Suggest{Text: "clear", Description: "clear screen"}},
|
||||
{Suggest: cli.Suggest{Text: "scan", Description: "scan for bridges"}},
|
||||
{Suggest: cli.Suggest{Text: "exit", Description: "exit ziggs"}},
|
||||
{Suggest: cli.Suggest{Text: "quit", Description: "exit ziggs"}},
|
||||
{Suggest: cli.Suggest{Text: "set", Description: "set state of target"}},
|
||||
{Suggest: cli.Suggest{Text: "use", Description: "select bridge to perform actions on"}},
|
||||
}
|
||||
for _, sug := range suggestions[0] {
|
||||
sug.requires = map[int][]string{}
|
||||
sug.root = true
|
||||
}
|
||||
suggestions[1] = []completion{
|
||||
{Suggest: cli.Suggest{Text: "group", Description: "target group"}},
|
||||
{Suggest: cli.Suggest{Text: "light", Description: "target light"}},
|
||||
}
|
||||
for _, sug := range suggestions[1] {
|
||||
sug.requires = map[int][]string{0: {"set", "s"}}
|
||||
sug.root = false
|
||||
}
|
||||
}
|
||||
|
||||
func processGroups(grps map[string]*huego.Group) {
|
||||
for grp, g := range grps {
|
||||
suffix := ""
|
||||
if g.Type != "" {
|
||||
suffix = " (" + g.Type + ")"
|
||||
}
|
||||
suggestions[2] = append(suggestions[2],
|
||||
completion{
|
||||
Suggest: cli.Suggest{
|
||||
Text: grp,
|
||||
Description: "Group" + suffix,
|
||||
},
|
||||
requires: map[int][]string{
|
||||
0: {"set", "s"},
|
||||
1: {"group", "g"},
|
||||
},
|
||||
root: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processLights() {
|
||||
for lt, l := range ziggy.Lucifer.Lights {
|
||||
suffix := ""
|
||||
if l.Type != "" {
|
||||
suffix = " (" + l.Type + ")"
|
||||
}
|
||||
suggestions[2] = append(suggestions[2],
|
||||
completion{
|
||||
Suggest: cli.Suggest{
|
||||
Text: lt,
|
||||
Description: "Light" + suffix,
|
||||
},
|
||||
requires: map[int][]string{
|
||||
0: {"set", "s"},
|
||||
1: {"light", "l"},
|
||||
},
|
||||
root: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func processBridges() {
|
||||
for brd, b := range ziggy.Lucifer.Bridges {
|
||||
suggestions[1] = append(suggestions[1],
|
||||
completion{
|
||||
Suggest: cli.Suggest{
|
||||
Text: brd,
|
||||
Description: "Bridge: " + b.Host,
|
||||
},
|
||||
requires: map[int][]string{0: {"use", "u"}},
|
||||
root: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func completer(in cli.Document) []cli.Suggest {
|
||||
c := in.CurrentLine()
|
||||
if c == "" {
|
||||
return []cli.Suggest{}
|
||||
infields := strings.Fields(c)
|
||||
var head = len(infields) - 1
|
||||
if len(infields) == 0 {
|
||||
head = 0
|
||||
}
|
||||
// args := strings.Fields(c)
|
||||
var set []cli.Suggest
|
||||
for command, subcommand := range suggestions {
|
||||
head := in.CursorPositionCol()
|
||||
if head > len(command.Text) {
|
||||
head = len(command.Text)
|
||||
}
|
||||
tmpl := &cli.Document{Text: command.Text}
|
||||
one := tmpl.GetWordAfterCursor()
|
||||
if one != "" && one != command.Text {
|
||||
set = append(set, cli.Suggest{Text: tmpl.Text})
|
||||
}
|
||||
if one == "use" && len(subcommand) > 1 {
|
||||
set = append(set, cli.Suggest{Text: tmpl.Text})
|
||||
}
|
||||
for _, a := range subcommand {
|
||||
if head > len(tmpl.Text+a.Text)+1 {
|
||||
continue
|
||||
}
|
||||
tmpl = &cli.Document{Text: tmpl.Text + " " + a.Text}
|
||||
two := tmpl.GetWordAfterCursorWithSpace()
|
||||
if two != "" {
|
||||
set = append(set, cli.Suggest{Text: tmpl.Text})
|
||||
}
|
||||
var sugs []cli.Suggest
|
||||
for _, sug := range suggestions[head] {
|
||||
if sug.qualifies(c) && strings.HasPrefix(sug.Text, in.GetWordBeforeCursor()) {
|
||||
sugs = append(sugs, sug.Suggest)
|
||||
}
|
||||
}
|
||||
return cli.FilterHasPrefix(set, c, false)
|
||||
return sugs
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ func cpuLoad(ctx context.Context) (chan int, error) {
|
||||
loadChan := make(chan int, 10)
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
time.Sleep(2 * time.Second)
|
||||
cpu, err := syStats.GetCPU()
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -28,6 +28,7 @@ type Meta struct {
|
||||
Bridges map[string]*Bridge
|
||||
Lights map[string]*HueLight
|
||||
Switches map[string]*huego.Sensor
|
||||
Groups map[string]*huego.Group
|
||||
*sync.RWMutex
|
||||
}
|
||||
|
||||
@ -255,7 +256,11 @@ func (c *Bridge) getLights() error {
|
||||
newlight.Log().Trace().Msg("+")
|
||||
c.HueLights = append(c.HueLights, newlight)
|
||||
Lucifer.Lock()
|
||||
Lucifer.Lights[light.UniqueID] = newlight
|
||||
name := strings.ReplaceAll(newlight.Name, " ", "_")
|
||||
if _, ok := Lucifer.Lights[name]; ok {
|
||||
name = fmt.Sprintf("%s_%d", name, 1)
|
||||
}
|
||||
Lucifer.Lights[name] = newlight
|
||||
Lucifer.Unlock()
|
||||
}
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user