You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

185 lines
4.4 KiB

package main
import (
"context"
"fmt"
"git.aiterp.net/lucifer/new-server/app/client"
"git.aiterp.net/lucifer/new-server/models"
"log"
"os"
"strings"
)
func handlerCmd(
ctx context.Context,
c client.Client,
) {
cmd := parseCommand(os.Args[2:])
switch cmd.Name {
case "list":
handlers, err := c.GetHandlers(ctx)
if err != nil {
log.Fatalln(err)
}
WriteHandlerInfoTable(os.Stdout, handlers)
case "add":
model := models.EventHandler{}
// Event name
model.EventName = cmd.Params.Get(0).StringOr("")
if len(model.EventName) == 0 {
log.Fatalln("Event name needed!")
}
// Search
fetchStr := cmd.Params.Get(1).String()
if fetchStr == nil {
log.Fatalln("Search filter needed!")
}
model.TargetKind, model.TargetValue = models.ParseFetchString(*fetchStr)
model = applyCmdToHandler(model, cmd)
newHandler, err := c.AddHandler(ctx, model)
if err != nil {
log.Fatalln(err)
}
WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*newHandler})
case "edit":
id := cmd.Params.Get(0).IntOr(0)
if id == 0 {
log.Fatalln("ID missing")
}
model, err := c.GetHandler(ctx, id)
if err != nil {
log.Fatalln(err.Error())
}
eventStr := cmd.Params.Get("event").String()
if eventStr != nil {
model.EventName = *eventStr
}
fetchStr := cmd.Params.Get("search").String()
if fetchStr != nil {
model.TargetKind, model.TargetValue = models.ParseFetchString(*fetchStr)
}
modified := applyCmdToHandler(*model, cmd)
returned, err := c.PutHandler(ctx, &modified)
if err != nil {
log.Fatalln(err.Error())
}
WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*returned})
case "delete":
id := cmd.Params.Get(0).Int()
if id == nil {
log.Fatalln("ID missing")
}
handler, err := c.DeleteHandler(ctx, *id)
if err != nil {
log.Fatalln(err)
}
WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*handler})
default:
if cmd.Name != "help" {
log.Println("Unknown command:", cmd.Name)
}
_, _ = fmt.Fprintln(os.Stderr, helpString[1:])
}
}
func applyCmdToHandler(model models.EventHandler, cmd Command) models.EventHandler {
// Remove keys
for _, elem := range cmd.Params.Strings(1) {
if !strings.HasPrefix(elem, "-") {
continue
}
keyToRemove := elem[1:]
if strings.HasPrefix(keyToRemove, "conditions.") {
condKeyToRemove := keyToRemove[11:]
delete(model.Conditions, condKeyToRemove)
} else if strings.HasPrefix(keyToRemove, "fire.payload.") && model.Actions.FireEvent != nil {
firePayloadKeyToRemove := keyToRemove[13:]
delete(model.Actions.FireEvent.Payload, firePayloadKeyToRemove)
} else {
switch keyToRemove {
case "set-power":
model.Actions.SetPower = nil
case "set-color":
model.Actions.SetColor = nil
case "set-intensity":
model.Actions.SetIntensity = nil
case "add-intensity":
model.Actions.AddIntensity = nil
case "fire":
fallthrough
case "fire.name":
model.Actions.FireEvent = nil
case "from":
model.From = models.Never
case "to":
model.To = models.Never
case "set-scene":
model.Actions.SetScene = nil
case "push-scene":
model.Actions.PushScene = nil
}
}
}
// From / To
model.From = cmd.Params.Get("from").TimeOfDayOr(models.Never)
model.To = cmd.Params.Get("to").TimeOfDayOr(models.Never)
if model.From.IsNever() != model.To.IsNever() {
log.Fatalln("from and to must be specified together!")
}
// One shot
model.OneShot = cmd.Params.Get("one-shot").StringOr("false") == "true"
// Priority
model.Priority = cmd.Params.Get("priority").IntOr(100)
// Conditions
model.Conditions = cmd.Params.Subset("conditions").EventConditions()
// Power, Color, Intensity, Temperature
nds := cmd.Params.DeviceState("set-")
model.Actions.SetPower = nds.Power
model.Actions.SetColor = nds.Color
model.Actions.SetIntensity = nds.Intensity
// Add intensity
model.Actions.AddIntensity = cmd.Params.Get("add-intensity").Float()
// Fire
fireParams := cmd.Params.Subset("fire")
fireName := fireParams.Get("name").String()
if fireName != nil {
firePayloadParams := fireParams.Subset("payload")
model.Actions.FireEvent = &models.Event{
Name: *fireName,
Payload: make(map[string]string, len(firePayloadParams)),
}
for key, value := range firePayloadParams.StringMap() {
model.Actions.FireEvent.Payload[key] = value
}
}
// Scenes
model.Actions.SetScene = cmd.Params.SceneAssignment("set-")
model.Actions.PushScene = cmd.Params.SceneAssignment("push-")
return model
}