single.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. package identify
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. )
  8. // SingleItem Nv和Ov的组合规则:
  9. // 1. Nv是什么 || Nv不是什么
  10. // 2. Ov是什么 || Ov不是什么
  11. //
  12. // 1与2的布尔运行结果交叉后, 得到4种组合 00, 01, 10, 11.
  13. // 一个事件的判断, 就处在[00, 01, 10, 11]的其中, 有一项为nil, 则表示该项直接通过
  14. // 多个事件, 就判断多个[00, 01, 10, 11], 所以得出以下结论:
  15. // 针对设备配置如下规则:
  16. //
  17. // {
  18. // "EventName 1": {
  19. // "NvIn": [1,2,3,4],
  20. // "NvNotIn": [5,6,7,8],
  21. // "OvIn": [1,2,3,4],
  22. // "OvNotIn": [5,6,7,8],
  23. // },
  24. // "EventName 2": {
  25. // "NvIn": [1,2,3,4],
  26. // "NvNotIn": [5,6,7,8],
  27. // "OvNotIn": [5,6,7,8],
  28. // },
  29. // ......
  30. // }
  31. type SingleItem struct {
  32. nv ItemValue // 当前值
  33. ov ItemValue // 上一次的值
  34. rules map[EventName]Rule
  35. vars map[string]string
  36. }
  37. func (s *SingleItem) Check(ov, nv ItemValue) EventName {
  38. defer func() {
  39. s.nv = ""
  40. s.ov = ""
  41. }()
  42. s.nv = nv
  43. s.ov = ov
  44. for event, rule := range s.rules {
  45. if s.check(rule) {
  46. return event
  47. }
  48. }
  49. return ""
  50. }
  51. func (s *SingleItem) checkForMulti(ov, nv ItemValue, rule Rule) bool {
  52. if ov == "" || nv == "" {
  53. return false
  54. }
  55. s.ov = ov
  56. s.nv = nv
  57. defer func() {
  58. s.nv = ""
  59. s.ov = ""
  60. }()
  61. var ovIn, ovNotIn, nvIn, nvNotIn = true, true, true, true
  62. if rule.OvIn != nil {
  63. ovIn = s.ovIn(rule.OvIn)
  64. }
  65. if rule.OvNotIn != nil {
  66. ovNotIn = s.ovNotIn(rule.OvNotIn)
  67. }
  68. if rule.NvIn != nil {
  69. nvIn = s.nvIn(rule.NvIn)
  70. }
  71. if rule.NvNotIn != nil {
  72. nvNotIn = s.nvNotIn(rule.NvNotIn)
  73. }
  74. return ovIn && ovNotIn && nvIn && nvNotIn
  75. }
  76. func (s *SingleItem) check(rule Rule) bool {
  77. if s.ov == "" || s.nv == "" {
  78. return false
  79. }
  80. var ovIn, ovNotIn, nvIn, nvNotIn = true, true, true, true
  81. if rule.OvIn != nil {
  82. ovIn = s.ovIn(rule.OvIn)
  83. }
  84. if rule.OvNotIn != nil {
  85. ovNotIn = s.ovNotIn(rule.OvNotIn)
  86. }
  87. if rule.NvIn != nil {
  88. nvIn = s.nvIn(rule.NvIn)
  89. }
  90. if rule.NvNotIn != nil {
  91. nvNotIn = s.nvNotIn(rule.NvNotIn)
  92. }
  93. return ovIn && ovNotIn && nvIn && nvNotIn
  94. }
  95. func (s *SingleItem) ovIn(slice []ItemValue) bool {
  96. b := true
  97. if slice != nil && s.inSlice(slice, s.ov) == false {
  98. b = false
  99. }
  100. return b
  101. }
  102. func (s *SingleItem) ovNotIn(slice []ItemValue) bool {
  103. b := true
  104. if slice != nil && s.inSlice(slice, s.ov) == true {
  105. b = false
  106. }
  107. return b
  108. }
  109. func (s *SingleItem) nvIn(slice []ItemValue) bool {
  110. b := true
  111. if slice != nil && s.inSlice(slice, s.nv) == false {
  112. b = false
  113. }
  114. return b
  115. }
  116. func (s *SingleItem) nvNotIn(slice []ItemValue) bool {
  117. b := true
  118. if slice != nil && s.inSlice(slice, s.nv) == true {
  119. b = false
  120. }
  121. return b
  122. }
  123. func (s *SingleItem) inSlice(slice []ItemValue, v ItemValue) bool {
  124. for _, s2 := range slice {
  125. s1 := s.transVar(s2)
  126. if s1 == v {
  127. return true
  128. }
  129. // 数字比较
  130. if _, err := strconv.ParseInt(s1, 10, 64); err != nil {
  131. return s.compare(s1, v)
  132. }
  133. }
  134. return false
  135. }
  136. func (s *SingleItem) transVar(v ItemValue) ItemValue {
  137. v = strings.Replace(v, "$nv", s.nv, 10)
  138. v = strings.Replace(v, "$ov", s.ov, 10)
  139. if strings.Index(v, "$") > -1 && len(s.vars) > 0 {
  140. for k, kv := range s.vars {
  141. v = strings.Replace(v, "$"+k, kv, 10)
  142. }
  143. //varName := v[1:len(v)]
  144. //if val, ok := s.vars[varName]; ok {
  145. // v = val
  146. //}
  147. }
  148. if strings.Index(v, "...") == -1 {
  149. v = s.calc(v)
  150. } else {
  151. vl := strings.Split(v, "...")
  152. if len(vl) != 2 {
  153. return v
  154. } else {
  155. return fmt.Sprintf("%s...%s", s.calc(vl[0]), s.calc(vl[1]))
  156. }
  157. }
  158. return v
  159. }
  160. func (s *SingleItem) compare(r string, v string) bool {
  161. if strings.Index(r, "...") > -1 {
  162. return s.compareRange(r, v)
  163. } else if strings.Index(r, " ") > 1 {
  164. return s.compareLogic(r, v)
  165. }
  166. return false
  167. }
  168. func (s *SingleItem) compareRange(r string, v string) bool {
  169. rl := strings.Split(r, "...")
  170. if len(rl) != 2 {
  171. return false
  172. }
  173. var min, max, vi int64 = 0, 0, 0
  174. if tmin, err := strconv.ParseInt(strings.TrimSpace(rl[0]), 10, 64); err == nil {
  175. min = tmin
  176. } else {
  177. return false
  178. }
  179. if tmax, err := strconv.ParseInt(strings.TrimSpace(rl[1]), 10, 64); err == nil {
  180. max = tmax
  181. } else {
  182. return false
  183. }
  184. if tvi, err := strconv.ParseInt(strings.TrimSpace(v), 10, 64); err == nil {
  185. vi = tvi
  186. } else {
  187. return false
  188. }
  189. return min <= vi && vi <= max
  190. }
  191. func (s *SingleItem) SetVars(vars map[ItemName]ItemValue) {
  192. s.vars = vars
  193. }
  194. func (s *SingleItem) calc(v string) string {
  195. if strings.Index(v, "+") > 1 {
  196. vl := strings.Split(v, "+")
  197. if len(vl) != 2 {
  198. return v
  199. }
  200. var st, nd int64
  201. var err error
  202. if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
  203. return v
  204. }
  205. if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
  206. return v
  207. }
  208. return fmt.Sprintf("%d", st+nd)
  209. }
  210. if strings.Index(v, "-") > 1 {
  211. vl := strings.Split(v, "-")
  212. if len(vl) != 2 {
  213. return v
  214. }
  215. var st, nd int64
  216. var err error
  217. if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
  218. return v
  219. }
  220. if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
  221. return v
  222. }
  223. return fmt.Sprintf("%d", st-nd)
  224. }
  225. if strings.Index(v, "*") > 1 {
  226. vl := strings.Split(v, "*")
  227. if len(vl) != 2 {
  228. return v
  229. }
  230. var st, nd int64
  231. var err error
  232. if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
  233. return v
  234. }
  235. if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
  236. return v
  237. }
  238. return fmt.Sprintf("%d", st*nd)
  239. }
  240. if strings.Index(v, "/") > 1 {
  241. vl := strings.Split(v, "/")
  242. if len(vl) != 2 {
  243. return v
  244. }
  245. var st, nd int64
  246. var err error
  247. if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
  248. return v
  249. }
  250. if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
  251. return v
  252. }
  253. return fmt.Sprintf("%d", st/nd)
  254. }
  255. if strings.Index(v, "%") > 1 {
  256. vl := strings.Split(v, "%")
  257. if len(vl) != 2 {
  258. return v
  259. }
  260. var st, nd int64
  261. var err error
  262. if st, err = strconv.ParseInt(strings.TrimSpace(vl[0]), 10, 64); err != nil {
  263. return v
  264. }
  265. if nd, err = strconv.ParseInt(strings.TrimSpace(vl[1]), 10, 64); err != nil {
  266. return v
  267. }
  268. return fmt.Sprintf("%d", st%nd)
  269. }
  270. return v
  271. }
  272. func (s *SingleItem) compareLogic(r string, v string) bool {
  273. rl := strings.Split(r, " ")
  274. if len(rl) != 2 {
  275. return false
  276. }
  277. var ri, vi int64 = 0, 0
  278. if tri, err := strconv.ParseInt(strings.TrimSpace(rl[1]), 10, 64); err == nil {
  279. ri = tri
  280. } else {
  281. return false
  282. }
  283. if tvi, err := strconv.ParseInt(strings.TrimSpace(v), 10, 64); err == nil {
  284. vi = tvi
  285. } else {
  286. return false
  287. }
  288. switch rl[0] {
  289. case "<":
  290. return vi < ri
  291. case "<=":
  292. return vi <= ri
  293. case ">":
  294. return vi > ri
  295. case ">=":
  296. return vi >= ri
  297. case "!=":
  298. return vi != ri
  299. }
  300. return false
  301. }
  302. // NewSingleCheck 生成一个检测对象, 之后调用Check来获得事件名称
  303. func NewSingleCheck(rules map[EventName]Rule) *SingleItem {
  304. return &SingleItem{
  305. rules: rules,
  306. vars: make(map[string]string),
  307. }
  308. }
  309. // NewSingleCheck 生成一个检测对象, 之后调用Check来获得事件名称
  310. func newSingleCheckForMultiItem() *SingleItem {
  311. return &SingleItem{}
  312. }
  313. func StepTest(ov, nv, ruleString string) string {
  314. rules := make(map[string]Rule)
  315. err := json.Unmarshal([]byte(ruleString), &rules)
  316. if err != nil {
  317. println(err.Error())
  318. }
  319. return NewSingleCheck(rules).Check(ov, nv)
  320. }