package ruleserver import ( "fmt" "basic.com/valib/logger.git" "ruleprocess/structure" "strings" "time" ) var stopChan = make(chan bool) // 计数器map 独立任务的键是任务id拼接区域id 联动任务的键是groupid(能不能都用groupId?) var TimeEleList = make(map[string]*TimeElement) // 定时器元素 type TimeElement struct { N int // 按时间依次递减的当前值 InitN int // 赋值后就不变的初始值 BufferFlag int // 缓冲容错位 连续n帧false才为false AlarmFlag bool // 报警标志位 定时器开启后第一次报警时会被置为true 往后再来报警也不会插进ES CacheSdkData structure.ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧 GroupId string // 联动规则需要记录下此时的规则组id RuleResults []*RuleResult } type RuleResult struct { // 每个摄像机一个结构体 CameraId string // 摄像机id Sort int32 // 摄像机在规则组中序号 Result string // 摄像机过滤数据得出的结果 RuleWithPre string // 摄像机之间的连接符 CacheData structure.ResultMsg // 缓存当前帧数据 } func TimeTicker() { ticker := time.NewTicker(1 * time.Second) go func(ticker *time.Ticker) { defer ticker.Stop() for { select { case <-ticker.C: logger.Info("定时器执行单元", time.Now().Unix()) fmt.Println("定时器执行单元", time.Now().Unix()) // 每秒钟计数器池子里所有的计数器元素都减一,减到0的是该报警的 rw.Lock() for k, timeEle := range TimeEleList { if timeEle.N > 0 { timeEle.N = timeEle.N - 1 logger.Error("-------------------------------------打印定时器计数元素当前值-----------------------------------------:", timeEle.N) } if timeEle.GroupId != "" && timeEle.N == 0 { // 说明是联动任务的时间窗口 到点儿了该销毁了,再来了再创建 delete(TimeEleList, k) } } rw.Unlock() case stop := <-stopChan: if stop { logger.Info("定时器结束") return //os.Exit(0) } } } }(ticker) } func StopTimeTicker() { stopChan <- true TimeTicker() } // 判断是否符合定时器条件 func TimerAlarm(oth *structure.Others, groupId string, result bool) (string) { var flagTime string // // 判断有无此规则组的定时器 flag := false rw.Lock() for k, _ := range TimeEleList { //logger.Debug("-----------------看看这个key和groupId", k, groupId) if strings.Contains(k, groupId) && k != groupId{ flag = true } } if flag { // 有定时器 if result { // 结果为真 for k, timeEle := range TimeEleList { if strings.Contains(k, groupId) && k != groupId{ if timeEle.N == 0 && timeEle.AlarmFlag { logger.Debug("-------------------------符合持续时间规则但并不是首次,不报警") flagTime = "11" oth.TimeLabel = flagTime } if timeEle.N == 0 && !timeEle.AlarmFlag { // 这组规则的定时器要全部等于0 暂且认为一组规则只有一个定时器 logger.Debug("———————————-------------首次符合持续时间规则并报警") flagTime = "10" timeEle.AlarmFlag = true oth.CacheData = []structure.ResultMsg{} oth.CacheData = append(oth.CacheData,timeEle.CacheSdkData) oth.TimeLabel = flagTime } if timeEle.N != 0 { flagTime = "00" // 有定时器但不为0把已打的标签删除 // args.RuleResult = nil logger.Debug("------------------------结果为真但计数器不到0,不报警,此时的计数器", k, "的值为:", timeEle.N) } } } } else { // 结果为假 for k, timeEle := range TimeEleList { if strings.Contains(k, groupId) && k != groupId{ if timeEle.AlarmFlag { if timeEle.BufferFlag == 0 { logger.Debug("------------------------------杀死定时器,报警此帧状态改变的数据,此时的计数器的值为", timeEle.N) flagTime = "12" oth.TimeLabel = flagTime delete(TimeEleList, k) } else { if timeEle.BufferFlag > 0 { logger.Debug("缓冲区减减") timeEle.BufferFlag-- } } } else { logger.Debug("-----------结果为假且不到0,杀死定时器") delete(TimeEleList, k) } } } } } else { // 无定时器 if result { flagTime = "01" oth.TimeLabel = flagTime } else { flagTime = "00" } } rw.Unlock() return flagTime } // 结构体根据某字段排序 type SubList []*RuleResult func (p SubList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p SubList) Len() int { return len(p) } func (p SubList) Less(i, j int) bool { return p[i].Sort < p[j].Sort } // 结构体根据某字段排序 type resultList []*structure.LittleRuleResult func (p resultList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p resultList) Len() int { return len(p) } func (p resultList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }