-
Notifications
You must be signed in to change notification settings - Fork 0
/
eval.go
111 lines (95 loc) · 1.95 KB
/
eval.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package goscript
import (
"fmt"
"github.com/antonmedv/expr"
"github.com/kjbreil/hass-ws/model"
"strconv"
"sync"
)
func Eval(exp ...string) []string {
return exp
}
func Evaluates(states States, eval []string) bool {
passed := false
for _, e := range eval {
if Evaluate(states, e) {
passed = true
}
}
return passed
}
func Evaluate(states States, eval string) bool {
var passed bool
atoi := expr.Function(
"float",
func(params ...any) (any, error) {
return strconv.ParseFloat(params[0].(string), 64)
},
)
program, err := expr.Compile(eval, expr.Env(map[string]interface{}{}),
expr.AllowUndefinedVariables(),
expr.AsBool(),
atoi)
if err != nil {
return false
}
env := make(map[string]interface{})
states.m.Lock()
defer states.m.Unlock()
if len(states.s) == 1 {
for _, state := range states.s {
env["state"] = state.State
// add attributes to env
if attr := state.Attributes; attr != nil {
for k, v := range attr {
for _, c := range program.Constants {
if _, ok := c.(string); ok {
if c.(string) == k {
env[c.(string)] = v
}
}
}
}
}
}
}
for _, state := range states.s {
env[state.DomainEntity] = state.State
if attr := state.Attributes; attr != nil {
for k, v := range attr {
for _, c := range program.Constants {
switch c.(type) {
case string:
if k == c.(string) {
env[fmt.Sprintf("%s.%s", state.DomainEntity, c.(string))] = v
}
}
}
}
}
}
evald, err := expr.Run(program, env)
if err != nil {
// TODO: Add error to some display
return false
}
if evald.(bool) && !passed {
passed = true
}
return passed
}
func (t *Trigger) eval(message *model.Message) bool {
passed := !(len(t.Eval) > 0)
states := States{
s: map[string]*State{
message.DomainEntity(): MessageState(message),
},
m: &sync.Mutex{},
}
for _, e := range t.Eval {
if Evaluate(states, e) {
passed = true
}
}
return passed
}