panlei
2019-09-16 716810adb573f7e6b40ab52887b5b158d9824817
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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的是该报警的
                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)
                    }
                }
            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
    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"
        }
    }
    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 }