package ruleserver
|
|
import (
|
"fmt"
|
"ruleprocess/logger"
|
"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 ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧
|
GroupId string // 联动规则需要记录下此时的规则组id
|
RuleResults []*RuleResult
|
}
|
type RuleResult struct {
|
// 每个摄像机一个结构体
|
CameraId string // 摄像机id
|
Sort int32 // 摄像机在规则组中序号
|
Result string // 摄像机过滤数据得出的结果
|
RuleWithPre string // 摄像机之间的连接符
|
CacheData 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 *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 = []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 []*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 }
|