package main
|
|
import (
|
"basic.com/pubsub/protomsg.git"
|
"basic.com/valib/logger.git"
|
"encoding/json"
|
"github.com/knetic/govaluate"
|
"plugin"
|
"ruleprocess/cache"
|
"ruleprocess/ruleserver"
|
"ruleprocess/structure"
|
"sort"
|
"strings"
|
"time"
|
)
|
|
func Entrance (args *structure.SdkDatas,groupRule protomsg.GroupRule,lable *structure.Others,message *protomsg.SdkMessage) (bool,string,string){
|
resultSplice := []*structure.LittleRuleResult{}
|
sdkNames := ""
|
polygonId := ""
|
// 先过完条件规则
|
for j := 0; j < len(groupRule.Rules); j++ {
|
if groupRule.Rules[j].SdkArgAlias == "score" || groupRule.Rules[j].SdkArgAlias == "proportion" || groupRule.Rules[j].SdkArgAlias == "size" || (groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule"){
|
for _, sdkData := range args.Sdkdata {
|
// 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据
|
sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
|
if err != nil {
|
logger.Error("没查到sdk的信息---", err)
|
}
|
ipcId := sdk.IpcId
|
sdkName := sdk.SdkName
|
//logger.Info("规则的ipcId与sdkData的IpcId:", ipcId, "===", sdkData.IpcId)
|
if ipcId == sdkData.IpcId {
|
//logger.Info("当前走的规则是--:", sdkName, "---","")
|
for _, areaMap := range sdkData.AreaMapList {
|
ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap,lable,args,message)
|
if ruleResult.Result != "" {
|
logger.Info("条件规则结果:", ruleResult.Result)
|
// 如果结果为真,把这条规则中的区域置为有效
|
if strings.Contains(ruleResult.Result, "true") {
|
areaMap.IsEffective = true
|
}
|
// 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
|
sdkNames = sdkName + " "
|
}
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
|
polygonId += groupRule.Rules[j].PolygonId + ","
|
}
|
resultSplice = append(resultSplice, &ruleResult)
|
}
|
}
|
}
|
}
|
}
|
}
|
// 人脸
|
for j := 0; j < len(groupRule.Rules); j++ {
|
if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule"{
|
for _, sdkData := range args.Sdkdata {
|
// 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据
|
sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
|
if err != nil {
|
logger.Error("没查到sdk的信息---", err)
|
}
|
ipcId := sdk.IpcId
|
sdkName := sdk.SdkName
|
//logger.Info("规则的ipcId与sdkData的IpcId:", ipcId, "===", sdkData.IpcId)
|
if ipcId == sdkData.IpcId {
|
//logger.Info("当前走的规则是--:", sdkName, "---","")
|
for _, areaMap := range sdkData.AreaMapList {
|
ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap,lable,args,message)
|
if ruleResult.Result != "" {
|
logger.Info("人脸比对规则结果:", ruleResult.Result)
|
// 如果结果为真,把这条规则中的区域置为有效
|
if strings.Contains(ruleResult.Result, "true") {
|
areaMap.IsEffective = true
|
}
|
// 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
|
sdkNames = sdkName + " "
|
}
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
|
polygonId += groupRule.Rules[j].PolygonId + ","
|
}
|
resultSplice = append(resultSplice, &ruleResult)
|
}
|
}
|
}
|
}
|
}
|
}
|
// 个体静止
|
for j := 0; j < len(groupRule.Rules); j++ {
|
if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a977" && groupRule.Rules[j].SdkArgAlias != "time_rule"{
|
for _, sdkData := range args.Sdkdata {
|
// 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据
|
sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
|
if err != nil {
|
logger.Error("没查到sdk的信息---", err)
|
}
|
ipcId := sdk.IpcId
|
sdkName := sdk.SdkName
|
//logger.Info("规则的ipcId与sdkData的IpcId:", ipcId, "===", sdkData.IpcId)
|
if ipcId == sdkData.IpcId {
|
//logger.Info("当前走的规则是--:", sdkName, "---","")
|
for _, areaMap := range sdkData.AreaMapList {
|
ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap,lable,args,message)
|
if ruleResult.Result != "" {
|
logger.Info("个体静止结果:", ruleResult.Result)
|
// 如果结果为真,把这条规则中的区域置为有效
|
if strings.Contains(ruleResult.Result, "true") {
|
areaMap.IsEffective = true
|
}
|
// 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
|
sdkNames = sdkName + " "
|
}
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
|
polygonId += groupRule.Rules[j].PolygonId + ","
|
}
|
resultSplice = append(resultSplice, &ruleResult)
|
}
|
}
|
}
|
}
|
}
|
}
|
// 再过其他数据 这步直接得到结果(真或假) 过目标数量
|
for j := 0; j < len(groupRule.Rules); j++ {
|
if groupRule.Rules[j].SdkArgAlias == "objCount" {
|
for _, sdkData := range args.Sdkdata {
|
// 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据
|
sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
|
if err != nil {
|
logger.Error("没查到sdk的信息---", err)
|
}
|
ipcId := sdk.IpcId
|
sdkName := sdk.SdkName
|
if ipcId == sdkData.IpcId {
|
for _, areaMap := range sdkData.AreaMapList {
|
ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap,lable,args,message)
|
if ruleResult.Result != "" {
|
if strings.Contains(ruleResult.Result, "true") {
|
areaMap.IsEffective = true
|
}
|
logger.Info("数量规则结果:", ruleResult.Result)
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
|
sdkNames = sdkName + " "
|
}
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
|
polygonId += groupRule.Rules[j].PolygonId + ","
|
}
|
resultSplice = append(resultSplice, &ruleResult)
|
}
|
}
|
}
|
}
|
}
|
}
|
// 这步过的是时间段规则(时间段等)
|
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
|
sdkName := sdk.SdkName
|
if ipcId == sdkData.IpcId {
|
for _, areaMap := range sdkData.AreaMapList {
|
ruleResult := timeRuleResult(groupRule.Rules[j], areaMap)
|
if ruleResult.Result != "" {
|
if strings.Contains(ruleResult.Result, "true") {
|
areaMap.IsEffective = true
|
}
|
logger.Info("时间规则结果:", ruleResult.Result)
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
|
sdkNames = sdkName + " "
|
}
|
if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
|
polygonId += groupRule.Rules[j].PolygonId + ","
|
}
|
resultSplice = append(resultSplice, &ruleResult)
|
}
|
}
|
}
|
}
|
}
|
// 将数组按sort排序
|
sort.Sort(ruleserver.ResultList(resultSplice))
|
// 排序后取各自的结果和连接符拼出规则表达式得出结果
|
completeFormula := ""
|
for _, va := range resultSplice {
|
completeFormula = completeFormula + va.Result
|
}
|
if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") || strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
|
// 以这些开头的基本是联动任务
|
if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") {
|
completeFormula = completeFormula[2:]
|
}
|
if strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
|
completeFormula = completeFormula[1:]
|
}
|
logger.Info("-------------------看看拔毛后的表达式:", completeFormula)
|
//expression, _ := govaluate.NewEvaluableExpression(completeFormula)
|
//result, _ := expression.Evaluate(nil) // 得到数学公式的结果
|
//return result.(bool)
|
}
|
if completeFormula != "" {
|
logger.Info("结果公式-----------:", completeFormula)
|
expression, err2 := govaluate.NewEvaluableExpression(completeFormula)
|
if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || err2 != nil {
|
panic("规则有误,得到的数学公式不可解析")
|
}
|
result, _ := expression.Evaluate(nil) // 得到数学公式的结果
|
return result.(bool),sdkNames,polygonId
|
} else {
|
return false,sdkNames,polygonId
|
}
|
}
|
|
func timeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
|
if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
|
if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
|
//logger.Info("----------当前时间规则:---------", rule)
|
// 根据放值字段里存的时间规则的id去另一个表里查需要比对的时间段(比如当前时间是周三,应根据区域id查出其周三的几个布防时间段,数组)
|
//logger.Info("时间规则的测试")
|
now := time.Now()
|
index := getIndexOfWeek(now.Weekday().String())
|
timeList := GetTimeById(rule.SdkArgValue, index)
|
//logger.Info("当天的时间段集合:----------", timeList)
|
//logger.Info("从数据库中查出的时间规则:", timeList)
|
// 判断图片数据的时间是否符合当前规则 在一个即为true,全不在为false
|
|
if rule.Operator == "satisfy" || rule.Operator == "==" { // 满足所选的时间规则
|
flag := "false"
|
for _, timeSlot := range timeList {
|
formula := "'" + timeSlot.Start + "'" + "<" + "'" + am.Time + "'"
|
expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
|
result, _ := expression.Evaluate(nil) // 得到数学公式的结果
|
|
formula1 := "'" + timeSlot.End + "'" + ">" + "'" + am.Time + "'"
|
expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
|
result1, _ := expression1.Evaluate(nil) // 得到数学公式的结果
|
//logger.Info("看看这两尊大神", result, result1)
|
if result.(bool) && result1.(bool) {
|
flag = "true"
|
break
|
}
|
}
|
return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
|
}
|
|
if rule.Operator == "unsatisfy" || rule.Operator == "!=" { // 不满足所选的时间规则
|
flag := "true"
|
for _, timeSlot := range timeList {
|
formula := "'" + timeSlot.Start + "'" + " < " + "'" + am.Time + "'"
|
//logger.Info("-----------------时间规则不满足的公式start:", formula)
|
expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
|
result, _ := expression.Evaluate(nil) // 得到数学公式的结果
|
|
formula1 := "'" + timeSlot.End + "'" + " > " + "'" + am.Time + "'"
|
//logger.Info("-----------------时间规则不满足的公式end:", formula1)
|
expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
|
result1, _ := expression1.Evaluate(nil) // 得到数学公式的结果
|
if result.(bool) && result1.(bool) {
|
flag = "false"
|
break
|
}
|
}
|
return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
|
}
|
|
}
|
}
|
return structure.LittleRuleResult{}
|
}
|
|
func CallSo(sdkId string,rule *protomsg.Rule, am *structure.AreaMap,lable *structure.Others,args *structure.SdkDatas,message *protomsg.SdkMessage) structure.LittleRuleResult{
|
// 根据sdkId查出其对应的sdk的soName,调用相应so的Entrance方法
|
var soName = ""
|
if sdkId == "812b674b-2375-4589-919a-5c1c3278a97e" {
|
soName = "face.so"
|
} else if sdkId == "812b674b-2375-4589-919a-5c1c3278a975"{
|
soName = "intrusion.so"
|
} else if sdkId == "812b674b-2375-4589-919a-5c1c3278a976" || sdkId == "812b674b-2375-4589-919a-5c1c3278a973" {
|
soName = "personUnsual.so"
|
} else if sdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
|
soName = "faceCompare.so"
|
} else if sdkId == "812b674b-2375-4589-919a-5c1c3278a977" {
|
soName = "static.so"
|
} else if sdkId == "812b674b-2375-4589-919a-5c1c3278a978" {
|
soName = "car.so"
|
}
|
//soInfo,errr := cache.GetSoInfoById(sdkId)
|
//if errr != nil {
|
// panic("没读到注册表")
|
//}
|
//soName := soInfo.SoName
|
p,err := plugin.Open("./algorithm/"+soName)
|
if err != nil {
|
panic(err)
|
}
|
f,err1 := p.Lookup("Entrance")
|
if err1 != nil {
|
panic("没有找到入口函数")
|
}
|
logger.Info("发给so的数据:",rule.SdkArgValue,rule.Operator,rule.SdkArgAlias)
|
ruleResult := f.(func(rule *protomsg.Rule, am *structure.AreaMap,lable *structure.Others, args *structure.SdkDatas,message *protomsg.SdkMessage)structure.LittleRuleResult)(rule,am,lable,args,message)
|
return ruleResult
|
}
|
|
// 取出某个时间规则的第几天的规则段集合
|
func GetTimeById(id string, index int) []structure.TimeRange {
|
_, cameraTimeRule := cache.GetTimeRuleById(id)
|
var timeRangeList []structure.Day
|
err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)
|
if err != nil {
|
logger.Error("取时间规则时反序列化错误!")
|
}
|
for _, timerange := range timeRangeList {
|
if timerange.Day == index {
|
//logger.Println("取到的时间规则:", timerange.TimeRange)
|
return timerange.TimeRange
|
}
|
}
|
return nil
|
}
|
|
// 根据传入的字符串得到其在一周内的索引 周一到周日分别对应1到7
|
func getIndexOfWeek(weekday string) int {
|
var weekdays = [7]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
|
for k, value := range weekdays {
|
if value == weekday {
|
return k + 1 // 因为数据库中存的是1-7代表的周一到周日
|
}
|
}
|
return 0
|
}
|