Dump and load config, successfully changed bridge IP from ziggs

This commit is contained in:
kayos@tcp.direct 2022-10-29 03:49:28 -07:00
parent a7224a6014
commit bdcdadce52
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
6 changed files with 115 additions and 46 deletions

@ -24,6 +24,8 @@ var (
cpuLastHue = make(map[int]uint16)
)
type reactor func(bridge *ziggy.Bridge, args []string) error
type ziggsCommand struct {
reactor reactor
description string
@ -31,8 +33,6 @@ type ziggsCommand struct {
isAlias bool
}
type reactor func(bridge *ziggy.Bridge, args []string) error
func newZiggsCommand(react reactor, desc string, aliases ...string) *ziggsCommand {
ret := &ziggsCommand{
reactor: react,
@ -255,7 +255,10 @@ func cmdRename(br *ziggy.Bridge, args []string) error {
// cmdDump exports a target object to a JSON file
func cmdDump(br *ziggy.Bridge, args []string) error {
if len(args) < 2 && args[0] != "all" {
if len(args) < 2 && args[0] != "all" && args[0] != "conf" && args[0] != "groups" &&
args[0] != "lights" && args[0] != "rules" && args[0] != "schedules" &&
args[0] != "sensors" && args[0] != "scenes" && args[0] != "resourcelinks" &&
args[0] != "config" {
return errors.New("not enough arguments")
}
var (
@ -285,6 +288,14 @@ func cmdDump(br *ziggy.Bridge, args []string) error {
case "bridge", "all":
target = br
name = br.Info.Name
case "config":
var conf *huego.Config
conf, err = br.GetConfig()
if err != nil {
return err
}
target = conf
name = br.Info.BridgeID
default:
return errors.New("invalid target type")
}
@ -299,16 +310,27 @@ func cmdDump(br *ziggy.Bridge, args []string) error {
// cmdLoad imports a target JSON object and attempts to apply it to an existing object
func cmdLoad(br *ziggy.Bridge, args []string) error {
if len(args) < 1 {
var js []byte
var err error
switch len(args) {
case 0, 1:
return errors.New("not enough arguments")
case 2:
js, err = os.ReadFile(args[1])
case 3:
js, err = os.ReadFile(args[2])
}
js, err := os.ReadFile(args[2])
if err != nil {
return err
}
if len(args) < 1 {
return errors.New("not enough arguments")
}
var target interface{}
switch args[0] {
case "light", "l":
target, err := br.FindLight(args[1])
target, err = br.FindLight(args[1])
if err != nil {
return err
}
@ -316,13 +338,13 @@ func cmdLoad(br *ziggy.Bridge, args []string) error {
if err := json.Unmarshal(js, &l); err != nil {
return err
}
if resp, err := br.UpdateLight(target.ID, *l); err != nil {
if resp, err := br.UpdateLight(target.(*huego.Light).ID, *l); err != nil {
return err
} else {
log.Info().Msgf("%v", resp)
}
case "group", "g":
target, err := br.FindGroup(args[1])
target, err = br.FindGroup(args[1])
if err != nil {
return err
}
@ -330,11 +352,21 @@ func cmdLoad(br *ziggy.Bridge, args []string) error {
if err := json.Unmarshal(js, &g); err != nil {
return err
}
if resp, err := br.UpdateGroup(target.ID, *g); err != nil {
if resp, err := br.UpdateGroup(target.(*huego.Group).ID, *g); err != nil {
return err
} else {
log.Info().Msgf("%v", resp)
}
case "config", "conf", "cfg":
var conf *huego.Config
if err = json.Unmarshal(js, &conf); err != nil {
return err
}
var resp *huego.Response
if resp, err = br.UpdateConfig(conf); err != nil {
return err
}
log.Info().Msgf("%v", resp)
case "schedule":
return errors.New("not implemented")
case "rule":

@ -23,6 +23,7 @@ type cmdTarget interface {
Col(color.Color) error
SetState(huego.State) error
Alert(string) error
Scene(string) error
}
func cmdSet(bridge *ziggy.Bridge, args []string) error {
@ -36,7 +37,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
var (
groupMap map[string]*huego.Group
lightMap map[string]*huego.Light
lightMap map[string]*ziggy.HueLight
actions []action
currentState *huego.State
argHead = -1
@ -194,7 +195,27 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
return alErr
})
case "cpu", "cpu2":
go cpuInit(args[argHead], bridge, target)
go func() {
if err := cpuInit(args[argHead], bridge, target); err != nil {
log.Error().Err(err).Msg("cpu init failed")
}
}()
log.Info().Msg("cpu load lighting started")
return nil
case "scene", "sc":
if len(args) == argHead-1 {
return errors.New("not enough arguments")
}
argHead++
targetScene := args[argHead]
actions = append(actions, func() error {
err := target.Scene(targetScene)
if err != nil {
err = fmt.Errorf("failed to set scene: %w", err)
}
return err
})
default:
return fmt.Errorf("unknown argument: " + args[argHead])
}
@ -206,7 +227,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error {
return errors.New("no target specified")
}
tg, tgok := target.(*huego.Group)
tl, tlok := target.(*huego.Light)
tl, tlok := target.(*ziggy.HueLight)
switch {
case tgok:
currentState = tg.State

@ -42,7 +42,7 @@ type Bridge struct {
config *config.KnownBridge
Info *huego.Config
log *zerolog.Logger
HueLights []*huego.Light
HueLights []*HueLight
*huego.Bridge
*sync.RWMutex
}
@ -58,20 +58,25 @@ func (c *Bridge) Log() *zerolog.Logger {
}
type HueLight struct {
l *huego.Light
*huego.Light
controller *Bridge
}
func (hl *HueLight) Scene(s string) error {
hl.Scene(s)
return nil
}
func (hl *HueLight) Log() *zerolog.Logger {
l := log.With().
Int("caller", hl.l.ID).
Str("name", hl.l.Name).
Bool("on", hl.l.IsOn()).Logger()
Int("caller", hl.ID).
Str("name", hl.Name).
Bool("on", hl.IsOn()).Logger()
return &l
}
func (hl *HueLight) GetPtr() (*huego.Light, error) {
return hl.controller.GetLight(hl.l.ID)
return hl.controller.GetLight(hl.ID)
}
func getProxiedBridge(cridge *config.KnownBridge) *huego.Bridge {
@ -137,12 +142,12 @@ const (
Toggle
)
type lCall func(light *huego.Light) (checkFunc, error)
type checkFunc func(light *huego.Light) bool
type lCall func(light *HueLight) (checkFunc, error)
type checkFunc func(light *HueLight) bool
var lightCallbacks = map[ToggleMode]lCall{
ToggleOn: func(light *huego.Light) (checkFunc, error) {
return func(light *huego.Light) bool {
ToggleOn: func(light *HueLight) (checkFunc, error) {
return func(light *HueLight) bool {
light.State = &huego.State{
On: true,
Bri: 100,
@ -156,8 +161,8 @@ var lightCallbacks = map[ToggleMode]lCall{
},
light.On()
},
ToggleOff: func(light *huego.Light) (checkFunc, error) {
return func(light *huego.Light) bool {
ToggleOff: func(light *HueLight) (checkFunc, error) {
return func(light *HueLight) bool {
light.State = &huego.State{
On: false,
Bri: 100,
@ -171,8 +176,8 @@ var lightCallbacks = map[ToggleMode]lCall{
},
light.Off()
},
/* ToggleDim: func(light *huego.Light) (checkFunc, error) {
return func(light *huego.Light) bool {
/* ToggleDim: func(light *HueLight) (checkFunc, error) {
return func(light *HueLight) bool {
if !light.IsOn() {
return false
}
@ -180,8 +185,8 @@ var lightCallbacks = map[ToggleMode]lCall{
},
light.On()
},*/
ToggleRainbow: func(light *huego.Light) (checkFunc, error) {
return func(light *huego.Light) bool {
ToggleRainbow: func(light *HueLight) (checkFunc, error) {
return func(light *HueLight) bool {
if !light.IsOn() {
return false
}
@ -191,7 +196,7 @@ var lightCallbacks = map[ToggleMode]lCall{
},
}
func Assert(ctx context.Context, l *huego.Light, mode ToggleMode) error {
func Assert(ctx context.Context, l *HueLight, mode ToggleMode) error {
act, ok := lightCallbacks[mode]
if !ok {
panic("not implemented")
@ -220,12 +225,12 @@ func Assert(ctx context.Context, l *huego.Light, mode ToggleMode) error {
}
}
func toggle(l *huego.Light, mode ToggleMode) error {
on := func(l *huego.Light) error {
func toggle(l *HueLight, mode ToggleMode) error {
on := func(l *HueLight) error {
log.Trace().Msg("turning light on...")
return l.On()
}
off := func(l *huego.Light) error {
off := func(l *HueLight) error {
log.Trace().Msg("turning light off...")
return l.Off()
}
@ -247,7 +252,7 @@ func toggle(l *huego.Light, mode ToggleMode) error {
return err
}
func ToggleLights(Lights []*huego.Light, mode ToggleMode) {
func ToggleLights(Lights []*HueLight, mode ToggleMode) {
for _, l := range Lights {
err := toggle(l, mode)
if err != nil {
@ -257,13 +262,20 @@ func ToggleLights(Lights []*huego.Light, mode ToggleMode) {
}
func (c *Bridge) getLights() error {
var err error
var l []huego.Light
var l []*HueLight
l, err = c.GetLights()
lit, err := c.GetLights()
if err != nil {
return err
}
for _, lght := range lit {
if lp, err := c.GetLight(lght.ID); err != nil {
log.Error().Err(err).Msg("failed to get light")
continue
} else {
l = append(l, &HueLight{Light: lp, controller: c})
}
}
if l == nil {
return fmt.Errorf("no lights found")
}
@ -274,16 +286,16 @@ func (c *Bridge) getLights() error {
return err
}
newlight := &HueLight{
l: lightPtr,
Light: lightPtr,
controller: c,
}
log.Debug().Interface("new light", newlight.l).Msg("+")
c.HueLights = append(c.HueLights, newlight.l)
log.Debug().Interface("new light", newlight.Light).Msg("+")
c.HueLights = append(c.HueLights, newlight)
}
return nil
}
func (c *Bridge) Lights() []*huego.Light {
func (c *Bridge) Lights() []*HueLight {
if len(c.HueLights) > 0 {
return c.HueLights
}

@ -8,8 +8,8 @@ type Multiplex struct {
bridges []*Bridge
}
func GetLightMap() map[string]*huego.Light {
var lightMap = make(map[string]*huego.Light)
func GetLightMap() map[string]*HueLight {
var lightMap = make(map[string]*HueLight)
for _, c := range Lucifer.Bridges {
ls, err := c.GetLights()
if err != nil {
@ -26,7 +26,7 @@ func GetLightMap() map[string]*huego.Light {
log.Warn().Msgf("duplicate light name %s on bridge %s - please rename", l.Name, c.ID)
continue
}
lightMap[l.Name] = light
lightMap[l.Name] = &HueLight{Light: light, controller: c}
}
}
return lightMap

@ -7,7 +7,7 @@ import (
"github.com/amimof/huego"
)
func (c *Bridge) FindLight(input string) (light *huego.Light, err error) {
func (c *Bridge) FindLight(input string) (light *HueLight, err error) {
var lightID int
if lightID, err = strconv.Atoi(input); err != nil {
targ, ok := GetLightMap()[input]
@ -16,7 +16,11 @@ func (c *Bridge) FindLight(input string) (light *huego.Light, err error) {
}
return targ, nil
}
return c.GetLight(lightID)
l, err := c.GetLight(lightID)
if err != nil {
return nil, err
}
return &HueLight{Light: l, controller: c}, nil
}
func (c *Bridge) FindGroup(input string) (light *huego.Group, err error) {

@ -33,7 +33,7 @@ func init() {
func TurnAll(Known []*ziggy.Bridge, mode ziggy.ToggleMode) {
for _, bridge := range Known {
for _, l := range ziggy.GetLightMap() {
go func(l *huego.Light) {
go func(l *ziggy.HueLight) {
log.Debug().
Str("caller", bridge.Host).
Str("type", l.ProductName).