factory command
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package handlerfactory
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v2"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FactoryConfig struct {
|
||||
Mode FCMOde `yaml:"mode"`
|
||||
Target string `yaml:"target"`
|
||||
SceneNames []string `yaml:"scenes"`
|
||||
TriggerDeviceID string `yaml:"trigger_device_id"`
|
||||
}
|
||||
|
||||
type FCMOde string
|
||||
|
||||
var (
|
||||
SceneDimmer FCMOde = "SceneDimmer"
|
||||
)
|
||||
|
||||
func ParseConfigs(reader io.Reader) ([]FactoryConfig, error) {
|
||||
readAll, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
splits := strings.Split(string(readAll), "\n---\n")
|
||||
configs := make([]FactoryConfig, 0, 8)
|
||||
for _, split := range splits {
|
||||
var factoryConfig FactoryConfig
|
||||
err := yaml.NewDecoder(strings.NewReader(split)).Decode(&factoryConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configs = append(configs, factoryConfig)
|
||||
}
|
||||
|
||||
return configs, nil
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package handlerfactory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.aiterp.net/lucifer/new-server/models"
|
||||
)
|
||||
|
||||
func CreateHandlers(
|
||||
config FactoryConfig,
|
||||
scenes []models.Scene,
|
||||
existing []models.EventHandler,
|
||||
) ([]models.EventHandler, []models.EventHandler) {
|
||||
switch config.Mode {
|
||||
case SceneDimmer:
|
||||
return sceneDimmer(config, scenes, existing)
|
||||
default:
|
||||
return []models.EventHandler{}, []models.EventHandler{}
|
||||
}
|
||||
}
|
||||
|
||||
func sceneDimmer(
|
||||
config FactoryConfig,
|
||||
scenes []models.Scene,
|
||||
existing []models.EventHandler,
|
||||
) ([]models.EventHandler, []models.EventHandler) {
|
||||
kind, refValue := models.ParseFetchString(config.Target)
|
||||
|
||||
toRemove := make([]models.EventHandler, 0, 8)
|
||||
for _, old := range existing {
|
||||
if old.Conditions["deviceId"].EQ == config.TriggerDeviceID {
|
||||
toRemove = append(toRemove, old)
|
||||
}
|
||||
}
|
||||
|
||||
resolvedScenes := make([]models.Scene, 0, len(config.SceneNames))
|
||||
for _, name := range config.SceneNames {
|
||||
for _, scene := range scenes {
|
||||
if name == scene.Name {
|
||||
resolvedScenes = append(resolvedScenes, scene)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(scenes) < 2 {
|
||||
return []models.EventHandler{}, []models.EventHandler{}
|
||||
}
|
||||
|
||||
handlers := make([]models.EventHandler, 0, len(scenes)+4)
|
||||
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "On"},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 100,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetPower: &myTrue},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "Off"},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 100,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetPower: &myFalse},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
|
||||
for i, scene := range resolvedScenes {
|
||||
if i > 0 {
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "DimDown"},
|
||||
"any.scene": {EQ: fmt.Sprintf("%d", scene.ID)},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 100,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetScene: &models.DeviceSceneAssignment{
|
||||
SceneID: resolvedScenes[i-1].ID,
|
||||
Group: refValue,
|
||||
DurationMS: 0,
|
||||
}},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
}
|
||||
|
||||
if i < len(resolvedScenes)-1 {
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "DimUp"},
|
||||
"any.scene": {EQ: fmt.Sprintf("%d", scene.ID)},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 100,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetScene: &models.DeviceSceneAssignment{
|
||||
SceneID: resolvedScenes[i+1].ID,
|
||||
Group: refValue,
|
||||
DurationMS: 0,
|
||||
}},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "DimDown"},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 90,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetScene: &models.DeviceSceneAssignment{
|
||||
SceneID: scenes[len(scenes)-1].ID,
|
||||
Group: refValue,
|
||||
DurationMS: 0,
|
||||
}},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
|
||||
handlers = append(handlers, models.EventHandler{
|
||||
EventName: "ButtonPressed",
|
||||
Conditions: map[string]models.EventCondition{
|
||||
"deviceId": {EQ: config.TriggerDeviceID},
|
||||
"buttonName": {EQ: "DimUp"},
|
||||
},
|
||||
OneShot: false,
|
||||
Priority: 90,
|
||||
TargetKind: kind,
|
||||
TargetValue: refValue,
|
||||
Actions: models.EventAction{SetScene: &models.DeviceSceneAssignment{
|
||||
SceneID: scenes[0].ID,
|
||||
Group: refValue,
|
||||
DurationMS: 0,
|
||||
}},
|
||||
From: -1,
|
||||
To: -1,
|
||||
})
|
||||
|
||||
return handlers, toRemove
|
||||
}
|
||||
|
||||
var myTrue = true
|
||||
var myFalse = false
|
||||
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.aiterp.net/lucifer/new-server/app/client"
|
||||
"git.aiterp.net/lucifer/new-server/app/services/handlerfactory"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func factoryCmd(
|
||||
ctx context.Context,
|
||||
c client.Client,
|
||||
) {
|
||||
cmd := parseCommand(os.Args[2:])
|
||||
|
||||
switch cmd.Name {
|
||||
case "run":
|
||||
fileName := cmd.Params.Get(0).String()
|
||||
if fileName == nil {
|
||||
log.Fatalln("Missing filename")
|
||||
}
|
||||
|
||||
scenes, err := c.GetScenes(ctx)
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
handlers, err := c.GetHandlers(ctx)
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
file, err := os.Open(*fileName)
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to open file:", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
configs, err := handlerfactory.ParseConfigs(file)
|
||||
for _, config := range configs {
|
||||
toAdd, toRemove := handlerfactory.CreateHandlers(config, scenes, handlers)
|
||||
|
||||
for _, removing := range toRemove {
|
||||
_, err := c.DeleteHandler(ctx, removing.ID)
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
log.Printf("Removed handler %d", removing.ID)
|
||||
}
|
||||
|
||||
for _, adding := range toAdd {
|
||||
res, err := c.AddHandler(ctx, adding)
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
log.Printf("Added handler %d", res.ID)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if cmd.Name != "help" {
|
||||
log.Println("Unknown command:", cmd.Name)
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintln(os.Stderr, helpString[1:])
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,23 @@ EVENT HANDLER COMMANDS
|
||||
<-fire> <-fire.payload.*>
|
||||
handler delete <id>
|
||||
|
||||
EVENT HANDLER FACTORY COMMANDS
|
||||
|
||||
factory run <file.yaml>
|
||||
|
||||
File example (use '---' to delimit multiple configs in one file):
|
||||
mode: SceneDimmer
|
||||
target: tag:Soverom
|
||||
scenes:
|
||||
- kveldslys
|
||||
- landskap
|
||||
- vasking
|
||||
trigger_device_id: 14
|
||||
---
|
||||
(more modes coming soon)
|
||||
|
||||
WARNING: Similar event handlers will be removed!
|
||||
|
||||
EVENT COMMANDS
|
||||
run <event name> <*=S>
|
||||
|
||||
|
||||
+5
-3
@@ -82,8 +82,8 @@ func main() {
|
||||
case "update":
|
||||
{
|
||||
devices, err := c.PutDevice(ctx, cmd.Params.Get(0).StringOr("all"), models.DeviceUpdate{
|
||||
Name: cmd.Params.Get("name").String(),
|
||||
Icon: cmd.Params.Get("icon").String(),
|
||||
Name: cmd.Params.Get("name").String(),
|
||||
Icon: cmd.Params.Get("icon").String(),
|
||||
UserProperties: cmd.Params.Subset("prop.").StringPtrMap(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -93,6 +93,9 @@ func main() {
|
||||
WriteDeviceInfoTable(os.Stdout, devices)
|
||||
}
|
||||
|
||||
case "factory":
|
||||
factoryCmd(ctx, c)
|
||||
|
||||
case "handler":
|
||||
handlerCmd(ctx, c)
|
||||
|
||||
@@ -126,4 +129,3 @@ func main() {
|
||||
_, _ = fmt.Fprintln(os.Stderr, helpString[1:])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user