| | |
| | | |
| | | import ( |
| | | "encoding/json" |
| | | "fmt" |
| | | "ruleprocess/cache" |
| | | "ruleprocess/logger" |
| | | "sort" |
| | |
| | | //protomsg.SdkMessage.TaskLabel.SdkmsgWithTask.sdkdata |
| | | |
| | | type ResultMsg struct { |
| | | protomsg.SdkMessage |
| | | *protomsg.SdkMessage |
| | | RuleResult map[string]interface{} // 过完规则后打的标签 |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 对单帧图像的判断 thisSdkDatas 当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas) |
| | | func Judge(args *SdkDatas) { |
| | | func Judge(args *SdkDatas,message *protomsg.SdkMessage) { |
| | | if len(args.Sdkdata) > 0 { |
| | | // 拿到本摄像机的区域 |
| | | cameraPolygons := GetPolygons(args.CameraId) |
| | |
| | | if len(temp) > 0 { |
| | | if ruleList[i].SetType == "linkTask" { |
| | | // groupId中含有link则为联动任务 |
| | | LinkTask(args, ruleList[i], taskId) |
| | | LinkTask(args, ruleList[i], taskId,message) |
| | | } else { |
| | | // 独立任务的处理 |
| | | RunRule(args, ruleList[i], taskId) |
| | | RunRule(args, ruleList[i], taskId,message) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string) bool { |
| | | func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string,message *protomsg.SdkMessage) bool { |
| | | defer func() { |
| | | if err := recover(); err != nil { |
| | | logger.Error("比对规则有误", err.(string)) |
| | |
| | | } |
| | | } |
| | | } |
| | | // 最后过持续时间等时间维度的条件 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | for _, sdkData := range args.Sdkdata { |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | | if err != nil { |
| | | logger.Error("没查到sdk的信息---", err) |
| | | } |
| | | ipcId := sdk.IpcId |
| | | if ipcId == sdkData.IpcId { |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | // 去开启一个定时器 |
| | | duration(groupRule.Rules[j], groupRule.GroupId, areaMap, args) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 将数组按sort排序 |
| | | sort.Sort(resultList(resultSplice)) |
| | | // 排序后取各自的结果和连接符拼出规则表达式得出结果 |
| | |
| | | panic("规则有误,得到的数学公式不可解析") |
| | | } |
| | | result, _ := expression.Evaluate(nil) // 得到数学公式的结果 |
| | | // 进行定时器的处理和判断 |
| | | timeFlag := TimerAlarm(args,groupRule.GroupId,result.(bool)) |
| | | if timeFlag == "01" || timeFlag == "10" || timeFlag == "11" { |
| | | |
| | | if result.(bool) { |
| | | // 最后成功报警才把符合条件的人脸数据塞进结果标签里 |
| | | // 配了人脸的算法才把人脸的数据甩出来打标签 |
| | | faces := []Arg{} |
| | |
| | | if args.RuleResult["face"] != nil { |
| | | logger.Info("-------------------face结果标签", len(args.RuleResult["face"].([]Arg))) |
| | | } |
| | | return true |
| | | // 最后过持续时间等时间维度的条件 把时间规则位置调整到这个位置是为了缓存数据 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | for _, sdkData := range args.Sdkdata { |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | | if err != nil { |
| | | logger.Error("没查到sdk的信息---", err) |
| | | } |
| | | ipcId := sdk.IpcId |
| | | if ipcId == sdkData.IpcId { |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | // 去开启一个定时器 |
| | | duration(groupRule.Rules[j], groupRule.GroupId, areaMap, args,message) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 进行定时器的处理和判断 |
| | | timeFlag := TimerAlarm(args,groupRule.GroupId,result.(bool)) |
| | | if timeFlag == "01" || timeFlag == "10" || timeFlag == "11" { // 满足定时器条件 |
| | | return true |
| | | } else { |
| | | return false |
| | | } |
| | | } else { |
| | | // 结果为假时也要走,有时候为假的状态反转数据也需要记录下来 |
| | | timeFlag := TimerAlarm(args,groupRule.GroupId,result.(bool)) |
| | | fmt.Println(timeFlag) |
| | | return false |
| | | } |
| | | } else { |
| | |
| | | if result { // 结果为真 |
| | | for k, timeEle := range TimeEleList { |
| | | if strings.Contains(k, groupId) { |
| | | if timeEle.N == 0 && timeEle.AlarmFlag { |
| | | logger.Debug("-------------------------符合持续时间规则但并不是首次,不报警") |
| | | flagTime = "11" |
| | | args.RuleResult["timeLabel"] = flagTime |
| | | } |
| | | if timeEle.N == 0 && !timeEle.AlarmFlag { // 这组规则的定时器要全部等于0 暂且认为一组规则只有一个定时器 |
| | | logger.Debug("———————————-------------首次符合持续时间规则并报警") |
| | | flagTime = "10" |
| | |
| | | args.RuleResult["cacheData"] = timeEle.CacheSdkData |
| | | args.RuleResult["timeLabel"] = flagTime |
| | | } |
| | | if timeEle.N == 0 && timeEle.AlarmFlag { |
| | | logger.Debug("-------------------------符合持续时间规则但并不是首次,不报警") |
| | | flagTime = "11" |
| | | args.RuleResult["timeLabel"] = flagTime |
| | | } |
| | | if timeEle.N != 0 { |
| | | flagTime = "00" |
| | | logger.Debug("------------------------结果为真但计数器不到0,不报警") |
| | | // 有定时器但不为0把已打的标签删除 |
| | | args.RuleResult = nil |
| | | logger.Debug("------------------------结果为真但计数器不到0,不报警,此时的计数器的值为:",timeEle.N) |
| | | } |
| | | } |
| | | } |
| | | } else { // 结果为假 |
| | | for k, timeEle := range TimeEleList { |
| | | if strings.Contains(k, groupId) { |
| | | logger.Debug("------------------------------重置定时器,此时的计数器的值为",timeEle.N) |
| | | timeEle.N = timeEle.InitN // 重置定时器 |
| | | timeEle.CacheSdkData = SdkDatas{} // 把缓存数据扔了 |
| | | flagTime = "12" |
| | | if timeEle.AlarmFlag { |
| | | logger.Debug("------------------------------杀死定时器,报警此帧状态改变的数据,此时的计数器的值为",timeEle.N) |
| | | flagTime = "12" |
| | | args.RuleResult["timeLabel"] = flagTime |
| | | delete(TimeEleList,k) |
| | | } else { |
| | | delete(TimeEleList,k) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } else { // 无定时器 |
| | | if result { |
| | | flagTime = "01" |
| | | args.RuleResult["timeLabel"] = flagTime |
| | | } else { |
| | | flagTime = "00" |
| | | } |
| | |
| | | } |
| | | |
| | | // 联动任务的处理 |
| | | func LinkTask(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string) { |
| | | func LinkTask(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string,message *protomsg.SdkMessage) { |
| | | // new一个定时器,如果以此groupId为标志的定时器不存在的话 |
| | | logger.Info("------------------------------------------当前是联动任务,规则是:", groupRule.GroupText) |
| | | var flag bool = true |
| | |
| | | } |
| | | } |
| | | // 往数组里赋值 |
| | | isOk := RunRule(args, groupRule, taskId) |
| | | isOk := RunRule(args, groupRule, taskId,message) |
| | | if isOk { |
| | | logger.Info("这帧图像在任务下的一整条规则下(联动任务下就是跟本摄像机像相关的小规则)的判断结果为true") |
| | | // 根据cameraId去更新或者插入结果,然后判断是否数组是否可以得出报警的结论 |
| | |
| | | } |
| | | // 先清空过滤后的数据,再往里塞本次过滤后的数据 |
| | | am.filterData = am.filterData[0:0] |
| | | logger.Debug("看看args:::::",args) |
| | | for _, arg := range args { |
| | | var formula string |
| | | if rule.SdkArgAlias == "score" { |
| | |
| | | } |
| | | |
| | | // 如果有持续时间条件维护开启一个定时器 |
| | | func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas) { |
| | | func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas,message *protomsg.SdkMessage) { |
| | | if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上 配置的算法要对的上 |
| | | if rule.SdkArgAlias == "duration" { // |
| | | // 先看看定时器元素队列中是否有这个摄像机这个区域的定时器,如果有就不能再次创建了 |
| | |
| | | |
| | | if flag { |
| | | timeLength, _ := strconv.Atoi(rule.SdkArgValue) |
| | | timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, CacheSdkData: *args} // 扔进去一个定时器元素(并缓存当前画面帧数据) |
| | | timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, CacheSdkData: ResultMsg{message,args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据) |
| | | //TimeEleList = make(map[string]timeElement) |
| | | TimeEleList[groupId+" "+rule.Id] = &timeEle // 定时器元素以摄像机id拼接区域id为键 |
| | | logger.Info("创建了计数器并且计数器集合为:", TimeEleList) |