better dump command and prolly other stuff (???)
This commit is contained in:
parent
1cdb1c33cb
commit
34c6a2e03d
1
go.mod
1
go.mod
|
@ -26,6 +26,7 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037 // indirect
|
||||
gioui.org v0.0.0-20230404150518-c0d3f67b0468 // indirect
|
||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -39,6 +39,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
|||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037 h1:+PdD6GLKejR9DizMAKT5DpSAkKswvZrurk1/eEt9+pw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
|
|
|
@ -28,7 +28,7 @@ var (
|
|||
|
||||
var noHist = map[string]bool{"clear": true, "exit": true, "quit": true}
|
||||
|
||||
// Interpret is where we will actuall define our Commands
|
||||
// Executor executes commands
|
||||
func Executor(cmd string) {
|
||||
if log == nil {
|
||||
log = config.StartLogger()
|
||||
|
@ -94,6 +94,8 @@ func Executor(cmd string) {
|
|||
}
|
||||
if newlevel, ok := levelsdebug[args[1]]; ok {
|
||||
zerolog.SetGlobalLevel(newlevel)
|
||||
nl := log.Level(newlevel)
|
||||
log = &nl
|
||||
return
|
||||
}
|
||||
if args[1] == "debugcli" || args[1] == "cli" {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"dario.cat/mergo"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/yunginnanet/huego"
|
||||
|
||||
|
@ -53,6 +54,15 @@ func newZiggsCommand(react reactor, desc string, requires int, aliases ...string
|
|||
|
||||
var Commands = make(map[string]*ziggsCommand)
|
||||
|
||||
func cmdRefresh(br *ziggy.Bridge, args []string) error {
|
||||
ziggy.NeedsUpdate()
|
||||
ziggy.GetGroupMap()
|
||||
ziggy.GetLightMap()
|
||||
ziggy.GetSceneMap()
|
||||
ziggy.GetSensorMap()
|
||||
return nil
|
||||
}
|
||||
|
||||
func cmdList(br *ziggy.Bridge, args []string) error {
|
||||
var runs = []reactor{cmdLights, cmdGroups, cmdScenes, cmdSensors}
|
||||
var cont = false
|
||||
|
@ -78,12 +88,33 @@ func cmdList(br *ziggy.Bridge, args []string) error {
|
|||
}
|
||||
|
||||
func cmdScenes(br *ziggy.Bridge, args []string) error {
|
||||
var targGroup *ziggy.HueGroup
|
||||
if len(args) > 0 {
|
||||
targGroup = ziggy.GetGroupMap()[args[0]]
|
||||
}
|
||||
scenes, err := br.GetScenes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, scene := range scenes {
|
||||
log.Info().Str("caller", strings.Split(br.Host, "://")[1]).
|
||||
scGrNum, numErr := strconv.Atoi(scene.Group)
|
||||
if numErr != nil {
|
||||
continue
|
||||
}
|
||||
grp, gerr := br.GetGroup(scGrNum)
|
||||
if gerr == nil {
|
||||
scene.Group = grp.Name
|
||||
}
|
||||
if gerr == nil && targGroup != nil {
|
||||
if targGroup.ID != scGrNum {
|
||||
continue
|
||||
}
|
||||
}
|
||||
/*for _, lstate := range scene.LightStates {
|
||||
// lstate.
|
||||
}*/
|
||||
|
||||
log.Info().Str("caller", scene.Group).
|
||||
Str("ID", scene.ID).Msgf("Scene: %s", scene.Name)
|
||||
log.Trace().Caller().Msgf("%v", spew.Sprint(scene))
|
||||
}
|
||||
|
@ -175,6 +206,9 @@ func cmdDelete(br *ziggy.Bridge, args []string) error {
|
|||
if len(args) < 2 {
|
||||
return errors.New("not enough arguments")
|
||||
}
|
||||
|
||||
defer ziggy.NeedsUpdate()
|
||||
|
||||
confirm := func() bool {
|
||||
log.Info().Msgf("Are you sure you want to delete the %s identified as %s? [y/N]", args[0], args[1])
|
||||
var input string
|
||||
|
@ -231,6 +265,9 @@ func cmdCp(br *ziggy.Bridge, args []string) error {
|
|||
if len(args) < 2 {
|
||||
return errors.New("not enough arguments")
|
||||
}
|
||||
|
||||
defer ziggy.NeedsUpdate()
|
||||
|
||||
var (
|
||||
targetLight *ziggy.HueLight
|
||||
targetGroup *ziggy.HueGroup
|
||||
|
@ -267,6 +304,9 @@ func cmdRename(br *ziggy.Bridge, args []string) error {
|
|||
target renameable
|
||||
err error
|
||||
)
|
||||
|
||||
defer ziggy.NeedsUpdate()
|
||||
|
||||
switch args[0] {
|
||||
case "light", "l":
|
||||
target, err = br.FindLight(args[1])
|
||||
|
@ -287,6 +327,19 @@ func cmdRename(br *ziggy.Bridge, args []string) error {
|
|||
return target.Rename(args[2])
|
||||
}
|
||||
|
||||
type dumpTarget struct {
|
||||
Name string
|
||||
Object any
|
||||
ParentFolder string
|
||||
}
|
||||
|
||||
func newTarget(name string, obj any) dumpTarget {
|
||||
return dumpTarget{
|
||||
Name: name,
|
||||
Object: obj,
|
||||
}
|
||||
}
|
||||
|
||||
// cmdDump exports a target object to a JSON file
|
||||
func cmdDump(br *ziggy.Bridge, args []string) error {
|
||||
if len(args) < 2 && args[0] != "all" && args[0] != "conf" && args[0] != "groups" &&
|
||||
|
@ -296,12 +349,13 @@ func cmdDump(br *ziggy.Bridge, args []string) error {
|
|||
return errors.New("not enough arguments")
|
||||
}
|
||||
var (
|
||||
target interface{}
|
||||
name string
|
||||
err error
|
||||
targets []dumpTarget
|
||||
err error
|
||||
)
|
||||
switch args[0] {
|
||||
case "light", "l":
|
||||
var name string
|
||||
var target any
|
||||
target, err = br.FindLight(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -312,65 +366,162 @@ func cmdDump(br *ziggy.Bridge, args []string) error {
|
|||
} else {
|
||||
name = lght.Name
|
||||
}
|
||||
targets = append(targets, newTarget(name, target))
|
||||
case "group", "g":
|
||||
target, err = br.FindGroup(args[1])
|
||||
var target any
|
||||
target, err = br.GetGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name = target.(*ziggy.HueGroup).Name
|
||||
for _, g := range target.([]huego.Group) {
|
||||
if !strings.EqualFold(g.Name, args[1]) && !strings.EqualFold(strconv.Itoa(g.ID), args[1]) {
|
||||
continue
|
||||
}
|
||||
targets = append(targets, newTarget(g.Name, g))
|
||||
}
|
||||
case "groups":
|
||||
var target any
|
||||
target, err = br.GetGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, g := range target.([]huego.Group) {
|
||||
targets = append(targets, newTarget(g.Name, g))
|
||||
}
|
||||
case "schedule":
|
||||
return errors.New("not implemented")
|
||||
case "rule":
|
||||
return errors.New("not implemented")
|
||||
case "rules":
|
||||
target, err = br.GetRules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "scenes":
|
||||
target, err = br.GetScenes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "schedules":
|
||||
var target any
|
||||
target, err = br.GetSchedules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range target.([]huego.Schedule) {
|
||||
if !strings.EqualFold(s.Name, args[1]) && !strings.EqualFold(strconv.Itoa(s.ID), args[1]) {
|
||||
continue
|
||||
}
|
||||
name := s.Name
|
||||
targets = append(targets, newTarget(name, s))
|
||||
break
|
||||
}
|
||||
case "rule":
|
||||
var target any
|
||||
target, err = br.GetRules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range target.([]huego.Rule) {
|
||||
if !strings.EqualFold(r.Name, args[1]) && !strings.EqualFold(strconv.Itoa(r.ID), args[1]) {
|
||||
continue
|
||||
}
|
||||
name := r.Name
|
||||
targets = append(targets, newTarget(name, r))
|
||||
break
|
||||
}
|
||||
case "rules":
|
||||
var target any
|
||||
target, err = br.GetRules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := "rules"
|
||||
targets = append(targets, newTarget(name, target))
|
||||
case "scenes":
|
||||
var scenes []huego.Scene
|
||||
scenes, err = br.GetScenes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range scenes {
|
||||
var scene *huego.Scene
|
||||
if scene, err = br.GetScene(s.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
var group *huego.Group
|
||||
var num int
|
||||
if num, err = strconv.Atoi(scene.Group); err != nil {
|
||||
group = nil
|
||||
}
|
||||
group, err = br.GetGroup(num)
|
||||
if err != nil {
|
||||
group = nil
|
||||
}
|
||||
|
||||
sc := newTarget(scene.Name, scene)
|
||||
if group != nil {
|
||||
sc.ParentFolder = group.Name
|
||||
}
|
||||
|
||||
if mergo.Merge(&sc.Object, s); err != nil {
|
||||
return err
|
||||
}
|
||||
targets = append(targets, sc)
|
||||
}
|
||||
case "schedules":
|
||||
var target any
|
||||
target, err = br.GetSchedules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range target.([]huego.Schedule) {
|
||||
name := s.Name
|
||||
targets = append(targets, newTarget(name, s))
|
||||
}
|
||||
case "sensor":
|
||||
return errors.New("not implemented")
|
||||
var target any
|
||||
target, err = br.GetSensors()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, sensor := range target.([]huego.Sensor) {
|
||||
name := sensor.Name
|
||||
targets = append(targets, newTarget(name, sensor))
|
||||
}
|
||||
case "bridge", "all":
|
||||
target = br
|
||||
name = br.Info.Name
|
||||
targets = append(targets, newTarget("bridge", br))
|
||||
case "config":
|
||||
var conf *huego.Config
|
||||
conf, err = br.GetConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target = conf
|
||||
name = br.Info.BridgeID
|
||||
name := br.Info.BridgeID
|
||||
targets = append(targets, newTarget(name, conf))
|
||||
default:
|
||||
return errors.New("invalid target type")
|
||||
}
|
||||
|
||||
js, err := json.Marshal(target)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, target := range targets {
|
||||
var wd string
|
||||
wd, err = os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wd = filepath.Join(wd, "dump", args[0])
|
||||
parentFolder := ""
|
||||
if target.ParentFolder != "" {
|
||||
targetDir := filepath.Join(wd, target.ParentFolder)
|
||||
if err = os.MkdirAll(targetDir, 0o755); err != nil { // #nosec
|
||||
return err
|
||||
}
|
||||
log.Info().Msgf("created folder: %s", targetDir)
|
||||
parentFolder = target.ParentFolder
|
||||
}
|
||||
var js []byte
|
||||
if js, err = json.Marshal(target.Object); err != nil {
|
||||
return err
|
||||
}
|
||||
fpath := filepath.Join(wd, target.Name+".json")
|
||||
if parentFolder != "" {
|
||||
fpath = filepath.Join(wd, parentFolder, target.Name+".json")
|
||||
}
|
||||
if err = os.WriteFile(fpath, js, 0o666); err != nil {
|
||||
return err
|
||||
}
|
||||
// get current working directory
|
||||
|
||||
log.Info().Msgf("dumped to: %s", fpath)
|
||||
}
|
||||
name = name + ".json"
|
||||
if err := os.WriteFile(name, js, 0o666); err != nil {
|
||||
return err
|
||||
}
|
||||
// get current working directory
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
// we can't get the current working directory, but the file was written successfully (in theory).
|
||||
// so just return nil without printing the path
|
||||
return nil
|
||||
}
|
||||
log.Info().Msgf("dumped to: %s", filepath.Join(wd, name))
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func cmdGetFullState(br *ziggy.Bridge, args []string) error {
|
||||
|
@ -482,6 +633,7 @@ func cmdLoad(br *ziggy.Bridge, args []string) error {
|
|||
}
|
||||
|
||||
func cmdAdopt(br *ziggy.Bridge, args []string) error {
|
||||
defer ziggy.NeedsUpdate()
|
||||
resp, err := br.FindLights()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -507,6 +659,7 @@ func cmdAdopt(br *ziggy.Bridge, args []string) error {
|
|||
}
|
||||
|
||||
func cmdReboot(br *ziggy.Bridge, args []string) error {
|
||||
defer ziggy.NeedsUpdate()
|
||||
resp, err := br.UpdateConfig(&huego.Config{Reboot: true})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -89,6 +89,7 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
Commands["refresh"] = newZiggsCommand(cmdRefresh, "refresh cached bridge data", 0)
|
||||
Commands["ls"] = newZiggsCommand(cmdList, "list all lights, groups, scenes, rules, and schedules", 0)
|
||||
Commands["schedules"] = newZiggsCommand(cmdSchedules, "list schedules", 0,
|
||||
"lssched", "crontab")
|
||||
|
|
|
@ -232,16 +232,17 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
|
|||
return ErrNotEnoughArguments
|
||||
}
|
||||
targetScene := strings.TrimSpace(args[argHead])
|
||||
log.Debug().Msgf("target scene: %s", targetScene)
|
||||
actions = append(actions, func() error {
|
||||
err := target.Scene(targetScene)
|
||||
if err != nil {
|
||||
targetScene = ziggy.GetSceneMap()[targetScene].ID
|
||||
err = target.Scene(targetScene)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to set scene: %w", err)
|
||||
}
|
||||
zhg := target.(*ziggy.HueGroup)
|
||||
if zhg == nil {
|
||||
return errors.New("target is not a group")
|
||||
}
|
||||
return err
|
||||
if ts := ziggy.GetSceneMap()[targetScene]; ts != nil {
|
||||
ts.Recall(zhg.ID)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("scene %s not found", targetScene)
|
||||
})
|
||||
|
||||
default:
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"git.tcp.direct/kayos/common/squish"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"git.tcp.direct/kayos/ziggs/internal/cli"
|
||||
"git.tcp.direct/kayos/ziggs/internal/config"
|
||||
|
||||
"github.com/charmbracelet/ssh"
|
||||
|
@ -47,7 +46,8 @@ func (s *Server) checkAuth(h ssh.Handler) ssh.Handler {
|
|||
|
||||
func (s *Server) ziggssh(h ssh.Handler) ssh.Handler {
|
||||
return func(ss ssh.Session) {
|
||||
cli.StartCLI()
|
||||
ss.
|
||||
cli.StartCLI()
|
||||
h(ss)
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ func (s *Server) ListenAndServe() error {
|
|||
wish.WithMiddleware(
|
||||
logging.Middleware(),
|
||||
s.checkAuth,
|
||||
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
@ -8,8 +8,28 @@ type Multiplex struct {
|
|||
bridges []*Bridge
|
||||
}
|
||||
|
||||
var (
|
||||
lightMap map[string]*HueLight
|
||||
groupMap map[string]*HueGroup
|
||||
sensorMap map[string]*HueSensor
|
||||
sceneMap map[string]*HueScene
|
||||
needsUpdate = 4
|
||||
)
|
||||
|
||||
func NeedsUpdate() {
|
||||
needsUpdate = 4
|
||||
}
|
||||
|
||||
func GetLightMap() map[string]*HueLight {
|
||||
var lightMap = make(map[string]*HueLight)
|
||||
if needsUpdate == 0 {
|
||||
return lightMap
|
||||
}
|
||||
|
||||
defer func() {
|
||||
needsUpdate--
|
||||
}()
|
||||
|
||||
lightMap = make(map[string]*HueLight)
|
||||
for _, c := range Lucifer.Bridges {
|
||||
ls, err := c.GetLights()
|
||||
if err != nil {
|
||||
|
@ -33,7 +53,15 @@ func GetLightMap() map[string]*HueLight {
|
|||
}
|
||||
|
||||
func GetGroupMap() map[string]*HueGroup {
|
||||
var groupMap = make(map[string]*HueGroup)
|
||||
if needsUpdate == 0 {
|
||||
return groupMap
|
||||
}
|
||||
|
||||
defer func() {
|
||||
needsUpdate--
|
||||
}()
|
||||
|
||||
groupMap = make(map[string]*HueGroup)
|
||||
for _, c := range Lucifer.Bridges {
|
||||
gs, err := c.GetGroups()
|
||||
if err != nil {
|
||||
|
@ -59,7 +87,15 @@ func GetGroupMap() map[string]*HueGroup {
|
|||
}
|
||||
|
||||
func GetSensorMap() map[string]*HueSensor {
|
||||
var sensorMap = make(map[string]*HueSensor)
|
||||
if needsUpdate == 0 {
|
||||
return sensorMap
|
||||
}
|
||||
|
||||
defer func() {
|
||||
needsUpdate--
|
||||
}()
|
||||
|
||||
sensorMap = make(map[string]*HueSensor)
|
||||
for _, c := range Lucifer.Bridges {
|
||||
ss, err := c.GetSensors()
|
||||
if err != nil {
|
||||
|
@ -83,7 +119,15 @@ func GetSensorMap() map[string]*HueSensor {
|
|||
}
|
||||
|
||||
func GetSceneMap() map[string]*HueScene {
|
||||
var sceneMap = make(map[string]*HueScene)
|
||||
if needsUpdate == 0 {
|
||||
return sceneMap
|
||||
}
|
||||
|
||||
defer func() {
|
||||
needsUpdate--
|
||||
}()
|
||||
|
||||
sceneMap = make(map[string]*HueScene)
|
||||
for _, c := range Lucifer.Bridges {
|
||||
scs, err := c.GetScenes()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue