Browse Source

add support for invoking and assigning scenes by name.

feature-colorvalue2 3.6.0
Gisle Aune 3 years ago
parent
commit
cedd0d1d28
  1. 28
      app/api/devices.go
  2. 16
      app/api/scenes.go
  3. 17
      cmd/lucy/scenecmd.go
  4. 4
      internal/drivers/hue/driver.go
  5. 10
      internal/mysql/scenerepo.go
  6. 2
      models/scene.go

28
app/api/devices.go

@ -218,14 +218,28 @@ func Devices(r gin.IRoutes) {
return []models.Device{}, nil return []models.Device{}, nil
} }
_, err = config.SceneRepository().Find(ctxOf(c), body.SceneID)
if err != nil {
return nil, err
}
if body.DurationMS < 0 {
body.DurationMS = 0
var scene *models.Scene
if body.SceneName != "" {
scene, err = config.SceneRepository().FindName(ctxOf(c), body.SceneName)
if err != nil {
return nil, err
}
if body.DurationMS < 0 {
body.DurationMS = 0
}
body.StartTime = time.Now()
body.SceneID = scene.ID
} else {
scene, err = config.SceneRepository().Find(ctxOf(c), body.SceneID)
if err != nil {
return nil, err
}
if body.DurationMS < 0 {
body.DurationMS = 0
}
body.StartTime = time.Now()
body.SceneName = scene.Name
} }
body.StartTime = time.Now()
pushMode := c.Query("push") == "true" pushMode := c.Query("push") == "true"
for i := range devices { for i := range devices {

16
app/api/scenes.go

@ -5,15 +5,27 @@ import (
"git.aiterp.net/lucifer/new-server/app/services/publisher" "git.aiterp.net/lucifer/new-server/app/services/publisher"
"git.aiterp.net/lucifer/new-server/models" "git.aiterp.net/lucifer/new-server/models"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"regexp"
) )
func Scenes(r gin.IRoutes) { func Scenes(r gin.IRoutes) {
nonNumericRegex := regexp.MustCompile("[a-zA-Z ]")
findScene := func(c *gin.Context) (*models.Scene, error) {
param := c.Param("id")
if nonNumericRegex.MatchString(param) {
return config.SceneRepository().FindName(ctxOf(c), param)
} else {
return config.SceneRepository().Find(ctxOf(c), intParam(c, "id"))
}
}
r.GET("", handler(func(c *gin.Context) (interface{}, error) { r.GET("", handler(func(c *gin.Context) (interface{}, error) {
return config.SceneRepository().FetchAll(ctxOf(c)) return config.SceneRepository().FetchAll(ctxOf(c))
})) }))
r.GET("/:id", handler(func(c *gin.Context) (interface{}, error) { r.GET("/:id", handler(func(c *gin.Context) (interface{}, error) {
return config.SceneRepository().Find(ctxOf(c), intParam(c, "id"))
return findScene(c)
})) }))
r.POST("", handler(func(c *gin.Context) (interface{}, error) { r.POST("", handler(func(c *gin.Context) (interface{}, error) {
@ -45,7 +57,7 @@ func Scenes(r gin.IRoutes) {
return nil, err return nil, err
} }
scene, err := config.SceneRepository().Find(ctxOf(c), intParam(c, "id"))
scene, err := findScene(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }

17
cmd/lucy/scenecmd.go

@ -93,15 +93,22 @@ func sceneCmd(
{ {
fetch := cmd.Params.Get(0).String() fetch := cmd.Params.Get(0).String()
id := cmd.Params.Get(1).Int() id := cmd.Params.Get(1).Int()
if fetch == nil || id == nil {
log.Println("Usage: lucy scene assign <fetch> <id> <group=S> <duration=I>")
name := cmd.Params.Get(1).String()
if fetch == nil || (id == nil && name == nil) {
log.Println("Usage: lucy scene assign <fetch> <id|name> <group=S> <duration=I>")
} }
devices, err := c.AssignDevice(ctx, *fetch, cmd.Name == "push", models.DeviceSceneAssignment{
SceneID: *id,
assignment := models.DeviceSceneAssignment{
Group: cmd.Params.Get("group").StringOr(*fetch), Group: cmd.Params.Get("group").StringOr(*fetch),
DurationMS: int64(cmd.Params.Get("duration").IntOr(0)), DurationMS: int64(cmd.Params.Get("duration").IntOr(0)),
})
}
if id != nil {
assignment.SceneID = *id
} else {
assignment.SceneName = *name
}
devices, err := c.AssignDevice(ctx, *fetch, cmd.Name == "push", assignment)
if err != nil { if err != nil {
log.Println("Could not assign devices:", err) log.Println("Could not assign devices:", err)
return return

4
internal/drivers/hue/driver.go

@ -322,8 +322,8 @@ func (d *Driver) Run(ctx context.Context, bridge models.Bridge, ch chan<- models
return err return err
} }
fastTicker := time.NewTicker(time.Second / 10)
slowTicker := time.NewTicker(time.Second / 3)
fastTicker := time.NewTicker(time.Second / 5)
slowTicker := time.NewTicker(time.Second / 2)
selectedTicker := fastTicker selectedTicker := fastTicker
ticksUntilRefresh := 0 ticksUntilRefresh := 0
ticksSinceChange := 0 ticksSinceChange := 0

10
internal/mysql/scenerepo.go

@ -29,6 +29,16 @@ func (r *SceneRepo) Find(ctx context.Context, id int) (*models.Scene, error) {
return r.populateOne(&scene) return r.populateOne(&scene)
} }
func (r *SceneRepo) FindName(ctx context.Context, name string) (*models.Scene, error) {
var scene sceneRecord
err := r.DBX.GetContext(ctx, &scene, "SELECT * FROM scene WHERE name = ?", name)
if err != nil {
return nil, dbErr(err)
}
return r.populateOne(&scene)
}
func (r *SceneRepo) FetchAll(ctx context.Context) ([]models.Scene, error) { func (r *SceneRepo) FetchAll(ctx context.Context) ([]models.Scene, error) {
scenes := make([]sceneRecord, 0, 8) scenes := make([]sceneRecord, 0, 8)
err := r.DBX.SelectContext(ctx, &scenes, "SELECT * FROM scene") err := r.DBX.SelectContext(ctx, &scenes, "SELECT * FROM scene")

2
models/scene.go

@ -299,6 +299,7 @@ const (
// instance is created for the group. // instance is created for the group.
type DeviceSceneAssignment struct { type DeviceSceneAssignment struct {
SceneID int `json:"sceneId"` SceneID int `json:"sceneId"`
SceneName string `json:"sceneName"`
Group string `json:"group"` Group string `json:"group"`
StartTime time.Time `json:"start"` StartTime time.Time `json:"start"`
DurationMS int64 `json:"durationMs"` DurationMS int64 `json:"durationMs"`
@ -306,6 +307,7 @@ type DeviceSceneAssignment struct {
type SceneRepository interface { type SceneRepository interface {
Find(ctx context.Context, id int) (*Scene, error) Find(ctx context.Context, id int) (*Scene, error)
FindName(ctx context.Context, name string) (*Scene, error)
FetchAll(ctx context.Context) ([]Scene, error) FetchAll(ctx context.Context) ([]Scene, error)
Save(ctx context.Context, bridge *Scene) error Save(ctx context.Context, bridge *Scene) error
Delete(ctx context.Context, bridge *Scene) error Delete(ctx context.Context, bridge *Scene) error

Loading…
Cancel
Save