Lucy handler add

This commit is contained in:
Stian Fredrik Aune
2021-09-28 21:54:03 +02:00
parent 0cd325e8db
commit c7d7e264ca
10 changed files with 196 additions and 46 deletions
+67 -8
View File
@@ -1,15 +1,17 @@
package main
import (
"git.aiterp.net/lucifer/new-server/models"
"log"
"strconv"
"strings"
)
type Param struct {
Index int
Key string
Value string
Index int
Key string
Value string
Operator string
}
func (p *Param) String() *string {
@@ -28,7 +30,6 @@ func (p *Param) StringOr(fallback string) string {
return p.Value
}
func (p *Param) Int() *int {
if p == nil {
return nil
@@ -42,6 +43,15 @@ func (p *Param) Int() *int {
return &n
}
func (p *Param) IntOr(other int) int {
val := p.Int()
if val == nil {
return other
}
return *val
}
func (p *Param) Float() *float64 {
if p == nil {
return nil
@@ -108,7 +118,7 @@ func (p Params) Subset(prefix string) Params {
for _, param := range p {
if param.Index == -1 && strings.HasPrefix(param.Key, prefix) {
res = append(res, Param{Index: -1, Key: param.Key[len(prefix):], Value: param.Value})
res = append(res, Param{Index: -1, Key: param.Key[len(prefix):], Value: param.Value, Operator: param.Operator})
}
}
@@ -152,6 +162,34 @@ func (p Params) Strings(minIndex int) []string {
return res
}
func (p Params) EventConditions() map[string]models.EventCondition {
ecMap := make(map[string]models.EventCondition, len(p))
for _, param := range p {
element, ok := ecMap[param.Key]
if !ok {
element = models.EventCondition{}
}
switch param.Operator {
case "<":
element.LT = param.Value
case "<=":
element.LTE = param.Value
case ">=":
element.GTE = param.Value
case ">":
element.GT = param.Value
default:
element.EQ = param.Value
}
ecMap[param.Key] = element
}
return ecMap
}
type Command struct {
Name string
Params Params
@@ -169,10 +207,22 @@ func parseCommand(args []string) Command {
nextIndex := 0
for _, arg := range args[1:] {
kv := strings.SplitN(arg, "=", 2)
kvle := strings.SplitN(arg, "<=", 2)
kvge := strings.SplitN(arg, ">=", 2)
kvl := strings.SplitN(arg, "<", 2)
kvg := strings.SplitN(arg, ">", 2)
kve := strings.SplitN(arg, "=", 2)
if len(kv) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kv[0], Value: kv[1]})
if len(kvle) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvle[0], Value: kvle[1], Operator: "<="})
} else if len(kvge) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvge[0], Value: kvge[1], Operator: ">="})
} else if len(kvl) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvl[0], Value: kvl[1], Operator: "<"})
} else if len(kvg) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kvg[0], Value: kvg[1], Operator: ">"})
} else if len(kve) == 2 {
cmd.Params = append(cmd.Params, Param{Index: -1, Key: kve[0], Value: kve[1], Operator: "="})
} else {
cmd.Params = append(cmd.Params, Param{Index: nextIndex, Value: arg})
nextIndex += 1
@@ -181,3 +231,12 @@ func parseCommand(args []string) Command {
return cmd
}
func (cmd Command) NewDeviceState(prefix string) models.NewDeviceState {
return models.NewDeviceState{
Power: cmd.Params.Get(prefix + "power").Bool(),
Color: cmd.Params.Get(prefix + "color").String(),
Intensity: cmd.Params.Get(prefix + "intensity").Float(),
Temperature: cmd.Params.Get(prefix + "temperature").Int(),
}
}
+57 -1
View File
@@ -17,12 +17,68 @@ func handlerCmd(
switch cmd.Name {
case "list":
handlers, err := c.GetHandlers(ctx, cmd.Params.Get(0).StringOr("all"))
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)
// 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.NewDeviceState("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
}
}
newHandler, err := c.AddHandler(ctx, model)
if err != nil {
log.Fatalln(err)
}
WriteHandlerInfoTable(os.Stdout, []models.EventHandler{*newHandler})
case "delete":
id := cmd.Params.Get(0).Int()
if id == nil {
+13 -4
View File
@@ -7,16 +7,25 @@ EXAMPLES
lucy set tag:Hexagon color=hs:35,1 intensity=0.3
lucy run SetProfile name=evening
EVENT HANDLER COMMANDS
handler list
handler delete <id>
DEVICE COMMANDS
list <search>
set <search> <power=B> <color=C> <intensity=F> <temperature=N>
tag <search> <[+/-]tag-name>
update <search> <name=S> <icon=S> <prop.*=S/NULL>
EVENT HANDLER COMMANDS
handler list
handler add <event> <search> \
<one-shot=B> \
<priority=N> \
<conditions.[any.*|all.*|*][<|<=|=|=>|>]*> \
<set-power=B> <set-color=C> <set-intensity=F> <set-temperature=N> \
<add-intensity=F> \
<fire.name=S> <fire.payload.*=S>
handler delete <id>
EVENT COMMANDS
run <event name> <*=S>
NOTE: You may have to surround arguments including < or > with quotation marks!
`
+7 -7
View File
@@ -37,16 +37,15 @@ func main() {
log.Fatalln(err)
}
WriteDeviceStateTable(os.Stdout, devices)
if cmd.Params.Get("info").StringOr("false") == "true" {
WriteDeviceInfoTable(os.Stdout, devices)
} else {
WriteDeviceStateTable(os.Stdout, devices)
}
}
case "set":
{
devices, err := c.PutDeviceState(ctx, cmd.Params.Get(0).StringOr("all"), models.NewDeviceState{
Power: cmd.Params.Get("power").Bool(),
Color: cmd.Params.Get("color").String(),
Intensity: cmd.Params.Get("intensity").Float(),
Temperature: cmd.Params.Get("temperature").Int(),
})
devices, err := c.PutDeviceState(ctx, cmd.Params.Get(0).StringOr("all"), cmd.NewDeviceState(""))
if err != nil {
log.Fatalln(err)
}
@@ -124,3 +123,4 @@ func main() {
_, _ = fmt.Fprintln(os.Stderr, helpString[1:])
}
}
+3
View File
@@ -95,6 +95,9 @@ func WriteHandlerInfoTable(w io.Writer, handlers []models.EventHandler) {
if h.Actions.SetIntensity != nil {
actionStr += fmt.Sprintf("setIntensity=%.02f ", *h.Actions.SetIntensity)
}
if h.Actions.SetTemperature != nil {
actionStr += fmt.Sprintf("setTemperature=%d ", *h.Actions.SetTemperature)
}
if h.Actions.AddIntensity != nil {
actionStr += fmt.Sprintf("addIntensity=%.02f ", *h.Actions.AddIntensity)
}