瀏覽代碼

fix:
1. 点位事件可以读取当前上下文的值
2. 增加+-*/%的运算逻辑

gaoyagang 1 年之前
父節點
當前提交
cef83a9660
共有 3 個文件被更改,包括 132 次插入11 次删除
  1. 4 1
      identify/multi.go
  2. 8 5
      identify/multi_test.go
  3. 120 5
      identify/single.go

+ 4 - 1
identify/multi.go

@@ -1,6 +1,8 @@
 package identify
 
-import "encoding/json"
+import (
+	"encoding/json"
+)
 
 type MultiItem struct {
 	nvs map[ItemName]ItemValue // 当前值
@@ -28,6 +30,7 @@ func (m *MultiItem) Check(ovs, nvs map[ItemName]ItemValue) EventName {
 
 func (m *MultiItem) check(rules MultiRule) bool {
 	s := newSingleCheckForMultiItem()
+	s.SetVars(m.nvs)
 	// 判断指定的点位名, 是否通过了检测, 有一项不为true, 提前返回false
 	for itemName, rule := range rules {
 		if s.checkForMulti(m.ovs[itemName], m.nvs[itemName], rule) == false {

+ 8 - 5
identify/multi_test.go

@@ -6,16 +6,19 @@ import (
 
 func TestNewMultiCheck(t *testing.T) {
 	//map[string]MultiRule{}
-	ruleString := `{"过滤初期":{"step":{"NvIn":["26"]},"filter_time":{"NvIn":["360...660"]}}}`
+	// ``
+	ruleString := `{"过滤初期":{"C.M.UF1_DB@word_control":{"NvIn":["26"]},"C.M.UF1_DB@time_production":{"NvIn":["$C.M.UF1_DB@time_sp-360...$C.M.UF1_DB@time_sp-60"]},"C.M.UF1_DB@time_sp":{}}}`
 
 	ovs := map[string]string{
-		"step":        "25",
-		"filter_time": "361",
+		"C.M.UF1_DB@word_control":    "25",
+		"C.M.UF1_DB@time_production": "361",
+		"C.M.UF1_DB@time_sp":         "4500",
 	}
 
 	nvs := map[string]string{
-		"step":        "26",
-		"filter_time": "660",
+		"C.M.UF1_DB@word_control":    "26",
+		"C.M.UF1_DB@time_production": "8839",
+		"C.M.UF1_DB@time_sp":         "9000",
 	}
 
 	eventName := MultiTest(ovs, nvs, ruleString)

+ 120 - 5
identify/single.go

@@ -2,6 +2,7 @@ package identify
 
 import (
 	"encoding/json"
+	"fmt"
 	"strconv"
 	"strings"
 )
@@ -34,6 +35,7 @@ type SingleItem struct {
 	ov ItemValue // 上一次的值
 
 	rules map[EventName]Rule
+	vars  map[string]string
 }
 
 func (s *SingleItem) Check(ov, nv ItemValue) EventName {
@@ -143,7 +145,6 @@ func (s *SingleItem) nvNotIn(slice []ItemValue) bool {
 func (s *SingleItem) inSlice(slice []ItemValue, v ItemValue) bool {
 	for _, s2 := range slice {
 		s1 := s.transVar(s2)
-
 		if s1 == v {
 			return true
 		}
@@ -156,13 +157,29 @@ func (s *SingleItem) inSlice(slice []ItemValue, v ItemValue) bool {
 }
 
 func (s *SingleItem) transVar(v ItemValue) ItemValue {
-	if v == VAR_NV {
-		v = s.nv
+	v = strings.Replace(v, "$nv", s.nv, 10)
+	v = strings.Replace(v, "$ov", s.ov, 10)
+	if strings.Index(v, "$") > -1 && len(s.vars) > 0 {
+		for k, kv := range s.vars {
+			v = strings.Replace(v, "$"+k, kv, 10)
+		}
+		//varName := v[1:len(v)]
+		//if val, ok := s.vars[varName]; ok {
+		//	v = val
+		//}
 	}
 
-	if v == VAR_OV {
-		v = s.ov
+	if strings.Index(v, "...") == -1 {
+		v = s.calc(v)
+	} else {
+		vl := strings.Split(v, "...")
+		if len(vl) != 2 {
+			return v
+		} else {
+			return fmt.Sprintf("%s...%s", s.calc(vl[0]), s.calc(vl[1]))
+		}
 	}
+
 	return v
 }
 
@@ -204,6 +221,103 @@ func (s *SingleItem) compareRange(r string, v string) bool {
 	return min <= vi && vi <= max
 }
 
+func (s *SingleItem) SetVars(vars map[ItemName]ItemValue) {
+	s.vars = vars
+}
+
+func (s *SingleItem) calc(v string) string {
+	if strings.Index(v, "+") > 1 {
+		vl := strings.Split(v, "+")
+		if len(vl) != 2 {
+			return v
+		}
+		var st, nd int64
+		var err error
+		if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
+			return v
+		}
+
+		if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
+			return v
+		}
+
+		return fmt.Sprintf("%d", st+nd)
+	}
+
+	if strings.Index(v, "-") > 1 {
+		vl := strings.Split(v, "-")
+		if len(vl) != 2 {
+			return v
+		}
+		var st, nd int64
+		var err error
+		if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
+			return v
+		}
+
+		if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
+			return v
+		}
+
+		return fmt.Sprintf("%d", st-nd)
+	}
+
+	if strings.Index(v, "*") > 1 {
+		vl := strings.Split(v, "*")
+		if len(vl) != 2 {
+			return v
+		}
+		var st, nd int64
+		var err error
+		if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
+			return v
+		}
+
+		if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
+			return v
+		}
+
+		return fmt.Sprintf("%d", st*nd)
+	}
+
+	if strings.Index(v, "/") > 1 {
+		vl := strings.Split(v, "/")
+		if len(vl) != 2 {
+			return v
+		}
+		var st, nd int64
+		var err error
+		if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
+			return v
+		}
+
+		if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
+			return v
+		}
+
+		return fmt.Sprintf("%d", st/nd)
+	}
+
+	if strings.Index(v, "%") > 1 {
+		vl := strings.Split(v, "%")
+		if len(vl) != 2 {
+			return v
+		}
+		var st, nd int64
+		var err error
+		if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
+			return v
+		}
+
+		if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
+			return v
+		}
+
+		return fmt.Sprintf("%d", st%nd)
+	}
+	return v
+}
+
 func (s *SingleItem) compareLogic(r string, v string) bool {
 	rl := strings.Split(r, " ")
 	if len(rl) != 2 {
@@ -243,6 +357,7 @@ func (s *SingleItem) compareLogic(r string, v string) bool {
 func NewSingleCheck(rules map[EventName]Rule) *SingleItem {
 	return &SingleItem{
 		rules: rules,
+		vars:  make(map[string]string),
 	}
 }