liuxiaolong
2019-11-07 73e4d775a359b5490b5ebc1465f1b9d682a3bbe5
Merge branch 'module' of http://192.168.5.5:10010/r/ruleprocess into module
1个文件已删除
3个文件已添加
26个文件已修改
1993 ■■■■■ 已修改文件
algorithm/face/face.go 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/intrusion/intrusion.go 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/middleware/middleware.go 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/personUnsual/personUnsual.go 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/static/static.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/timeSlot/timeSlot.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cache/cache.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/EsClient.go 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/config.go 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/insertDataToEs.go 549 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/readyDataForLabel.go 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/req.go 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/ruleForLabel.go 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
logger/logger.go 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/attachInfo.go 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/geoPolygon.go 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/geoPolygon_test.go 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/personTrack.go 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 180 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/server.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/timeTicker.go 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/rule.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/105.jpg 补丁 | 查看 | 原始文档 | blame | 历史
util/simpleCV.go 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/simpleCV_test.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/upload.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/face/face.go
@@ -2,8 +2,8 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
)
@@ -15,42 +15,48 @@
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
        // 处理的是人脸算法 如果这条规则配置的是人脸算法,过滤完条件之后直接得出结果,因为肯定没有数量条件,自己拼接
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule"{ // 人脸比对
                //logger.Debug("当前小规则是:",rule)
                flag := "false"
                // 把没有相似者的人脸从filterData中删除
                for index := 0; index < len(am.FilterData); {
                    // 将达不到阈值的相似者从相似者数组中删除
                    logger.Info("看看相似者人数:",len(am.FilterData[index].Liker))
                    if len(am.FilterData[index].Liker) == 0 {
                        // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
                        am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
                    } else {
                        index++
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule" {
                if rule.RuleWithPre == "||" {
                    return structure.LittleRuleResult{}
                } else {
                    //logger.Debug("当前小规则是:",rule)
                    flag := "false"
                    // 把没有相似者的人脸从filterData中删除
                    for index := 0; index < len(am.FilterData); {
                        // 将达不到阈值的相似者从相似者数组中删除
                        logger.Info("看看相似者人数:",len(am.FilterData[index].Liker))
                        if len(am.FilterData[index].Liker) == 0 {
                            // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
                            am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
                        } else {
                            index++
                        }
                    }
                    if len(am.FilterData) > 0 {
                        flag = "true"
                    }
                    logger.Info("---------人脸比对符合条件的数量为:",len(am.FilterData))
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                }
                if len(am.FilterData) > 0 {
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:",len(am.FilterData))
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
                if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.TargetNum,"--区域--",am.AreaJson)
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.TargetNum)
                        var args []*structure.Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
                        } else {
                            args = am.Args
                            //不清空之前的过滤数据,继续塞
                            //logger.Info("没过滤的args的长度为:",len(args))
                        }
                        // 先清空过滤后的数据,再往里塞本次过滤后的数据
@@ -82,16 +88,16 @@
                        } else {
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return structure.LittleRuleResult{}
                    }
                } else {
                    return structure.LittleRuleResult{}
                } else if rule.SdkArgAlias == "" { // 什么参数都不配的情况
                    if am.TargetNum > 0 {
                        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                    } else {
                        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    }
                }
            } else {
                return structure.LittleRuleResult{}
            }
        } else {
            return structure.LittleRuleResult{}
        }
    }
    return structure.LittleRuleResult{}
}
algorithm/intrusion/intrusion.go
@@ -2,8 +2,8 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
)
@@ -11,12 +11,7 @@
//入侵算法
func Entrance(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
            logger.Debug("---------走了入侵算法",rule.Id,rule.SdkArgAlias,rule.Operator,rule.SdkArgValue,am.AreaId)
            return filterRule(rule, am)
        } else {
            return structure.LittleRuleResult{}
        }
        return filterRule(rule, am)
    } else {
        return structure.LittleRuleResult{}
    }
@@ -25,37 +20,48 @@
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    // 处理的都是yolo数据
    var args []*structure.Arg
    if rule.RuleWithPre == "&&" {
        args = am.FilterData
    } else {
        args = am.Args
    }
    // 先清空过滤后的数据,再往里塞本次过滤后的数据
    am.FilterData = am.FilterData[0:0]
    //logger.Debug("看看args:::::", args)
    for _, arg := range args {
        var formula string
        if rule.SdkArgAlias == "score" {
            formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前相似度小公式:", formula)
        } else if rule.SdkArgAlias == "proportion" {
            formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前占比小公式:", formula)
    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
        logger.Debug("---------走了入侵算法",rule.Id,rule.SdkArgAlias,rule.Operator,rule.SdkArgValue,am.AreaId)
        var args []*structure.Arg
        if rule.RuleWithPre == "&&" {
            args = am.FilterData
        } else {
            formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前尺寸小公式:", formula)
            args = am.Args
        }
        expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
        result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
        if result.(bool) {
            am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
        // 先清空过滤后的数据,再往里塞本次过滤后的数据
        am.FilterData = am.FilterData[0:0]
        //logger.Debug("看看args:::::", args)
        for _, arg := range args {
            var formula string
            if rule.SdkArgAlias == "score" {
                formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                logger.Info("当前相似度小公式:", formula)
            } else if rule.SdkArgAlias == "proportion" {
                formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                logger.Info("当前占比小公式:", formula)
            } else {
                formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                logger.Info("当前尺寸小公式:", formula)
            }
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
            if result.(bool) {
                am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
            }
        }
        am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
        if am.TargetNum > 0 {
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
        } else {
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
        }
    } else if rule.SdkArgAlias == "" {
        if am.TargetNum > 0 {
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
        } else {
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
        }
    }
    am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
    if am.TargetNum > 0 {
        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
    } else {
        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
    }
    return structure.LittleRuleResult{}
}
algorithm/middleware/middleware.go
@@ -2,11 +2,11 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "encoding/json"
    "github.com/knetic/govaluate"
    "plugin"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strings"
    "time"
@@ -40,11 +40,10 @@
                            }
                            // 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
                            if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
                                sdkNames = sdkName + ","
                                polygonId = groupRule.Rules[j].PolygonId + ","
                                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 + ","
                                polygonId = groupRule.Rules[j].PolygonId + " "
                            }
                            resultSplice = append(resultSplice, &ruleResult)
                        }
@@ -76,11 +75,10 @@
                            }
                            // 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
                            if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
                                sdkNames = sdkName + ","
                                polygonId = groupRule.Rules[j].PolygonId + ","
                                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 + ","
                                polygonId = groupRule.Rules[j].PolygonId + " "
                            }
                            resultSplice = append(resultSplice, &ruleResult)
                        }
@@ -109,10 +107,10 @@
                            }
                            logger.Info("数量规则结果:", ruleResult.Result)
                            if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
                                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 + ","
                                polygonId = groupRule.Rules[j].PolygonId + " "
                            }
                            resultSplice = append(resultSplice, &ruleResult)
                        }
@@ -139,10 +137,10 @@
                        }
                        logger.Info("时间规则结果:", ruleResult.Result)
                        if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
                            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 + ","
                            polygonId = groupRule.Rules[j].PolygonId + " "
                        }
                        resultSplice = append(resultSplice, &ruleResult)
                    }
algorithm/personUnsual/personUnsual.go
@@ -2,8 +2,8 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
)
@@ -27,39 +27,51 @@
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    // 处理的都是yolo数据
    var args []*structure.Arg
    if rule.RuleWithPre == "&&" {
        args = am.FilterData
    } else {
        args = am.Args
    }
    // 先清空过滤后的数据,再往里塞本次过滤后的数据
    am.FilterData = am.FilterData[0:0]
    //logger.Debug("看看args:::::", args)
    for _, arg := range args {
        var formula string
        if rule.SdkArgAlias == "score" {
            formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前相似度小公式:", formula)
        } else if rule.SdkArgAlias == "proportion" {
            formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前占比小公式:", formula)
        } else {
            formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            logger.Info("当前尺寸小公式:", formula)
        }
        expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
        result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
        if result.(bool) {
            am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
    if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
            var args []*structure.Arg
            if rule.RuleWithPre == "&&" {
                args = am.FilterData
            } else {
                args = am.Args
            }
            // 先清空过滤后的数据,再往里塞本次过滤后的数据
            am.FilterData = am.FilterData[0:0]
            //logger.Debug("看看args:::::", args)
            for _, arg := range args {
                var formula string
                if rule.SdkArgAlias == "score" {
                    formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                    logger.Info("当前相似度小公式:", formula)
                } else if rule.SdkArgAlias == "proportion" {
                    formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                    logger.Info("当前占比小公式:", formula)
                } else {
                    formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                    logger.Info("当前尺寸小公式:", formula)
                }
                expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                if result.(bool) {
                    am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
                }
            }
            am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
            if am.TargetNum > 0 {
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
            } else {
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
            }
        } else if rule.SdkArgAlias == "" {
            if am.TargetNum > 0 {
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
            } else {
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
            }
        }
    }
    am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
    if am.TargetNum > 0 {
        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
    } else {
        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
    }
    return structure.LittleRuleResult{}
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
algorithm/static/static.go
@@ -2,8 +2,8 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strconv"
algorithm/timeSlot/timeSlot.go
@@ -2,10 +2,10 @@
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "encoding/json"
    "github.com/knetic/govaluate"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "time"
)
cache/cache.go
@@ -5,11 +5,11 @@
    "basic.com/pubsub/cache.git/shardmap"
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/gopherdiscovery.git"
    "basic.com/valib/logger.git"
    "errors"
    "fmt"
    "github.com/gogo/protobuf/proto"
    "github.com/satori/go.uuid"
    "ruleprocess/logger"
    "strconv"
)
const (
go.mod
@@ -3,22 +3,23 @@
go 1.12
require (
    basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f
    basic.com/dbapi.git v0.0.0-20191025084729-a04db890e7b5
    basic.com/fileserver/WeedFSClient.git v0.0.0-20191105073656-98059e699477
    basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48
    basic.com/pubsub/protomsg.git v0.0.0-20190824080957-7b44351cb40b
    basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00
    basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051
    basic.com/pubsub/protomsg.git v0.0.0-20191105082616-7a5fc5da9c09
    basic.com/valib/deliver.git v0.0.0-20190927081905-2d390df9ede3
    basic.com/valib/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28
    basic.com/valib/gosdk.git v0.0.0-20190531034110-0062fdaaa05a // indirect
    basic.com/valib/logger.git v0.0.0-20190928113028-4907b08c4159
    basic.com/valib/shm.git v0.0.0-20190829074754-ad2e00879627 // indirect
    github.com/Microsoft/go-winio v0.4.12 // indirect
    github.com/ajg/form v1.5.1 // indirect
    github.com/go-yaml/yaml v2.1.0+incompatible
    github.com/gogo/protobuf v1.2.1
    github.com/golang/protobuf v1.3.1
    github.com/gorilla/websocket v1.4.0 // indirect
    github.com/knetic/govaluate v3.0.0+incompatible
    github.com/pierrec/lz4 v2.2.3+incompatible
    github.com/satori/go.uuid v1.2.0
    github.com/spf13/viper v1.4.0
    github.com/tmthrgd/go-sem v0.0.0-20160607101025-0214dbf53877 // indirect
    github.com/tmthrgd/go-shm v0.0.0-20170117044846-90afcfcd5ee9 // indirect
    github.com/tmthrgd/shm-go v0.0.0-20170130075737-7207ca97b290 // indirect
go.sum
@@ -1,58 +1,203 @@
basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f h1:m7ONW0VqagpmWppr6GSa2Gykid202vCbV9worYCM+pg=
basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f/go.mod h1:eDXPnxaz6jZPDvBSk7ya7oSASWPCuUEgRTJCjsfKt/Q=
basic.com/dbapi.git v0.0.0-20191025084729-a04db890e7b5 h1:OcZOgjBXfzhI1Ukxblacxu5xwKl448ADYyulJ02zdb8=
basic.com/dbapi.git v0.0.0-20191025084729-a04db890e7b5/go.mod h1:eDXPnxaz6jZPDvBSk7ya7oSASWPCuUEgRTJCjsfKt/Q=
basic.com/fileserver/WeedFSClient.git v0.0.0-20191105073656-98059e699477 h1:yr95Oko76zjDlPs60aHT2lAqApz8nzli9A6yJB/IrGA=
basic.com/fileserver/WeedFSClient.git v0.0.0-20191105073656-98059e699477/go.mod h1:oiXPn3wwwOi/Sbm6cDWpNWofoG5iV2Nb1V/DxLEAqYY=
basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48 h1:BBA30Rgljn6MRieC4gUncETJDyna3ObyubTo9HEQ2M0=
basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/protomsg.git v0.0.0-20190824080957-7b44351cb40b/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20190905061607-7b96dafe8f99 h1:YSmWZPp/mHoq+/L5d0iTsqjiCcVwZqEQRQAXxQFSbvY=
basic.com/pubsub/protomsg.git v0.0.0-20190905061607-7b96dafe8f99/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20191025080939-9b30ac3be52d h1:Lhny6vIq3GNjunE+r0ymLnpg+/n0lqwnsOAy6HbARfk=
basic.com/pubsub/protomsg.git v0.0.0-20191025080939-9b30ac3be52d/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20191105075705-11a3749018a7 h1:6B15QTE96XgpT2Ry9a3xhJZzxYvP6rClT3l4r2WHrjE=
basic.com/pubsub/protomsg.git v0.0.0-20191105075705-11a3749018a7/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20191105082616-7a5fc5da9c09 h1:wktnrfZLxcSEnmu/ptMdn4GF5UiHcUdRSlWQ0EllJxY=
basic.com/pubsub/protomsg.git v0.0.0-20191105082616-7a5fc5da9c09/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00 h1:sK+Tx7rvM9J2WnNIwrzMDjZSylWiKNfQO0prUBfKsDk=
basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00/go.mod h1:8by33F9E1w17Pw/rDgJGJXAo122w0wDENG14hiMS+RE=
basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051 h1:9flC2o3kasaM2Y6I+mY+mxmve/pyAY/UzGQZLT3lFHM=
basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051/go.mod h1:bkYiTUGzckyNOjAgn9rB/DOjFzwoSHJlruuWQ6hu6IY=
basic.com/valib/deliver.git v0.0.0-20190927081905-2d390df9ede3 h1:VY23IpugB/FsU2hSnVeLjZKX5cSgNmhcSEiw6vxX+bg=
basic.com/valib/deliver.git v0.0.0-20190927081905-2d390df9ede3/go.mod h1:bkYiTUGzckyNOjAgn9rB/DOjFzwoSHJlruuWQ6hu6IY=
basic.com/valib/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28 h1:3hejanzPEBvZSSvjIqayB83/6/6SLLrX9oNZAdiYELg=
basic.com/valib/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28/go.mod h1:CQ+UJyZV8MRzwwckncdUDu6/RDTKAzSIPCxc9tFcwPs=
basic.com/valib/gosdk.git v0.0.0-20190531034110-0062fdaaa05a h1:6QxKVo+2wR1fgqGVgpGJoQt9XZOqVkmxJCs1r7hJfJ8=
basic.com/valib/gosdk.git v0.0.0-20190531034110-0062fdaaa05a/go.mod h1:mT/jbyl3++GmYjh/jBF65Ein6O6/yd4qIQbSFMCZoE4=
basic.com/valib/logger.git v0.0.0-20190926101623-99e2471fbbf5 h1:kBGQ+7tbDY4kIyZJVK3gLqAFzK8zS7o7323pSgfXXBs=
basic.com/valib/logger.git v0.0.0-20190926101623-99e2471fbbf5/go.mod h1:SPlOGUUlxCscwF1dkqmLb0oJXVqg1uJ8hsPXLFxrw1M=
basic.com/valib/logger.git v0.0.0-20190927065828-cb651da7c223 h1:LPTDC1cOb2ZhuAkflqWXrIQ2RPYPS+ntoRgvpnZm4bY=
basic.com/valib/logger.git v0.0.0-20190927065828-cb651da7c223/go.mod h1:SPlOGUUlxCscwF1dkqmLb0oJXVqg1uJ8hsPXLFxrw1M=
basic.com/valib/logger.git v0.0.0-20190928113028-4907b08c4159 h1:e5KopUEW/E9qmE3gUS6m7uO+/ti/N2m8rMMHB/HVqPk=
basic.com/valib/logger.git v0.0.0-20190928113028-4907b08c4159/go.mod h1:SPlOGUUlxCscwF1dkqmLb0oJXVqg1uJ8hsPXLFxrw1M=
basic.com/valib/shm.git v0.0.0-20190829074754-ad2e00879627 h1:y0t0XG2uPSygF+hiSdLP3Lr959tip/FDPYJpHhbKRec=
basic.com/valib/shm.git v0.0.0-20190829074754-ad2e00879627/go.mod h1:yYRM7bM9y0KKd4IfNt3myjsvkFVFIIWNjsvK14tNbq4=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
code.cloudfoundry.org/bytefmt v0.0.0-20180906201452-2aa6f33b730c/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kirinlabs/HttpRequest v0.1.5 h1:BzOb6AmBii232R93birBsf663kt8N9y8N0TCQKoEzhA=
github.com/kirinlabs/HttpRequest v0.1.5/go.mod h1:XV38fA4rXZox83tlEV9KIQ7Cdsut319x6NGzVLuRlB8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/knetic/govaluate v3.0.0+incompatible h1:wtCEE87YYq68awKAV9kYkNDvxS7MDzO3ABbKgDqO+tI=
github.com/knetic/govaluate v3.0.0+incompatible/go.mod h1:7QMc3skGbZuD4ZSe6bVN885uWCaxvhpo1Fvwvgp7bF8=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pierrec/lz4 v2.2.3+incompatible h1:YpgKDCFg5dd0Eb+XlgrfJtH4fAqoRA1kBcKnBZ4EFSE=
github.com/pierrec/lz4 v2.2.3+incompatible/go.mod h1:g2rHQ0wsQlPM7GZ66p1EVBh+VdeJ8s60jWWxl1M9t1Q=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/schollz/progressbar/v2 v2.12.1/go.mod h1:fBI3onORwtNtwCWJHsrXtjE3QnJOtqIZrvr3rDaF7L0=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmthrgd/go-sem v0.0.0-20160607101025-0214dbf53877 h1:n65+IT/xy5+trHm3Zpg9+j7IO4n8pBcPzvaKbMolW8U=
github.com/tmthrgd/go-sem v0.0.0-20160607101025-0214dbf53877/go.mod h1:sgTk9wg3WurMlziuB3hcfgHYTz3pEkjQpSCTT8V2pW8=
github.com/tmthrgd/go-shm v0.0.0-20170117044846-90afcfcd5ee9 h1:uVRQSWD6TOlWlLJ7IYYmbjRr0Xg35ADFN89HGQLPFGI=
github.com/tmthrgd/go-shm v0.0.0-20170117044846-90afcfcd5ee9/go.mod h1:vy1jksyhzuQOMkHXMEi+X2bZ47ZeCn3QTnYdFBesABs=
github.com/tmthrgd/shm-go v0.0.0-20170130075737-7207ca97b290 h1:5zW+TRr0WH4uN72/E/XYwb1PcaYN5BIB/FUbcQ0nHr0=
github.com/tmthrgd/shm-go v0.0.0-20170130075737-7207ca97b290/go.mod h1:e9PZQr6zVezMTwj1v0j1YhGCNdS2zTCjXU9q9K+HHGk=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
gocv.io/x/gocv v0.20.0 h1:2q75zQ8Zel2tB69G6qrmf/E7EdvaCs90qvkHzdSBOAg=
gocv.io/x/gocv v0.20.0/go.mod h1:vZETJRwLnl11muQ6iL3q4ju+0oJRrdmYdv5xJTH7WYA=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:uPxWBzB3+mlnjy9W58qY1j/cjyFjutgw/Vhan2zLy/A=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
nanomsg.org/go-mangos v1.4.0 h1:pVRLnzXePdSbhWlWdSncYszTagERhMG5zK/vXYmbEdM=
nanomsg.org/go-mangos v1.4.0/go.mod h1:MOor8xUIgwsRMPpLr9xQxe7bT7rciibScOqVyztNxHQ=
insertdata/EsClient.go
@@ -1,17 +1,16 @@
package insertdata
import (
    "bytes"
    "encoding/json"
    "errors"
    "fmt"
    "io"
    "io/ioutil"
    "net/http"
    "ruleprocess/logger"
    "strconv"
    "strings"
    "time"
    "bytes"
)
type Reps struct {
insertdata/config.go
New file
@@ -0,0 +1,63 @@
package insertdata
import (
    "github.com/spf13/viper"
    "log"
)
type weedfs struct {
    Ip string `mapstructure: "ip"`
    UploadPort int `mapstructure: "uploadport"`
    VisitPort int `mapstructure: "visitport"`
}
var WeedFs = &weedfs{}
// wp add es 索引 以及 IP port
type esinfo struct {
    Masterip string      `mapstructure:"masterip"`
    Httpport string      `mapstructure:"httpport"`
    Shards string         `mapstructure:"shards"`
    EsIndex  esindexlist `mapstructure:"index"`
}
type esindexlist struct {
    VideoPersons   index `mapstructure:"videopersons"`
    DbTables       index `mapstructure:"dbtables"`
    Dbtablepersons index `mapstructure:"dbtablepersons"`
    Personaction   index `mapstructure:"personaction"`
}
type index struct {
    IndexName string `mapstructure:"index"`
    IndexType string `mapstructure:"type"`
}
type sopath struct {
    Ip string `mapstructure:"ip"`
    Port string `mapstructure:"port"`
}
var SoPath = &sopath{}
var EsInfo = &esinfo{}
// Init is an exported method that takes the environment starts the viper
// (external lib) and returns the configuration struct.
func Init(env string) {
    var err error
    viper.SetConfigType("yaml")
    viper.SetConfigName(env)
    viper.AddConfigPath("/opt/vasystem/config/")
    viper.AddConfigPath("")
    err = viper.ReadInConfig()
    if err != nil {
        log.Fatal("error on parsing configuration file")
    }
    viper.UnmarshalKey("es", EsInfo)
    viper.UnmarshalKey("weedfs", WeedFs)
    viper.UnmarshalKey("sopath",SoPath)
    //InitInsertEs()
}
insertdata/insertDataToEs.go
@@ -1,23 +1,21 @@
package insertdata
import (
    "basic.com/valib/logger.git"
    "encoding/base64"
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "net"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
    "time"
    "basic.com/pubsub/protomsg.git"
    "github.com/go-yaml/yaml"
    "github.com/golang/protobuf/proto"
    "github.com/satori/go.uuid"
    "ruleprocess/ruleserver"
    "ruleprocess/util"
    "ruleprocess/structure"
)
var weedfsUrl, videoPersonUrl, personAction string
@@ -31,55 +29,63 @@
    DbTablePersons string `yaml:"dbTablePersons"`
}
func init() {
    data, err := ioutil.ReadFile("./config/conf.yml")
    if err != nil {
        fmt.Println("读取配置文件出错--", err)
        logger.Error("读取配置文件出错--", err)
    }
    c := conf{}
    //把yaml形式的字符串解析成struct类型
    yaml.Unmarshal(data, &c)
    weedfsUrl = c.PhotoUrl
    videoPersonUrl = c.VideoPersons
    personAction = c.PersonAction
}
//func InitInsertEs() {
//    weedfsUrl = "http://"+WeedFs.Ip+":"+strconv.Itoa(WeedFs.UploadPort)+"/submit"
//    videoPersonUrl = "http://"+EsInfo.Masterip+":"+EsInfo.Httpport+"/"+EsInfo.EsIndex.VideoPersons.IndexName+"/"+EsInfo.EsIndex.VideoPersons.IndexType
//    personAction = "http://"+EsInfo.Masterip+":"+EsInfo.Httpport+"/"+EsInfo.EsIndex.Personaction.IndexName+"/"+EsInfo.EsIndex.Personaction.IndexType
//}
// 人脸的数据结构
type PerVideoPicture struct {
    Id              string                 `json:"id"`
    CameraId        string                 `json:"cameraId"`
    CameraAddr      string                 `json:"cameraAddr"`
    PicDate         string                 `json:"picDate"`
    PicMaxUrl       string                 `json:"picMaxUrl"`
    TaskId          string                 `json:"taskId"`
    TaskName        string                 `json:"taskName"`
    SdkName         string                 `json:"sdkName"`
    Content         string                 `json:"content"`
    AlarmRules      []AlarmRule            `json:"alarmRules"`
    LikeDate        string                 `json:"likeDate"`
    Sex             string                 `json:"sex"`
    Age             int32                  `json:"age"`
    AgeDescription  string                 `json:"ageDescription"`
    Race            string                 `json:"race"`
    SmileLevel      int32                  `json:"smileLevel"`
    BeautyLevel     int32                  `json:"beautyLevel"`
    FaceFeature     string                 `json:"faceFeature"`
    PicSmUrl        []string               `json:"picSmUrl"`
    VideoUrl        string                 `json:"videoUrl"`
    AnalyServerId   string                 `json:"analyServerId"`
    AnalyServerName string                 `json:"analyServerName"`
    AnalyServerIp   string                 `json:"analyServerIp"`
    ClusterId       string                 `json:"clusterId"`
    LinkId          string                 `json:"linkId"`
    DetectScore     float64                `json:"detectScore"`
    IsAlarm         int                    `json:"isAlarm"`
    IsAckAlarm      int                    `json:"isAckAlarm"`
    IsCollect       int                    `json:"isCollect"`
    IsDelete        int                    `json:"isDelete"`
    Id              string                `json:"id"`
    CameraId        string                `json:"cameraId"`
    CameraAddr      string                `json:"cameraAddr"`
    PicDate         string                `json:"picDate"`
    PicMaxUrl       string                `json:"picMaxUrl"`
    TaskId          string                `json:"taskId"`
    TaskName        string                `json:"taskName"`
    SdkName         string                `json:"sdkName"`
    Content         string                `json:"content"`
    AlarmRules      []AlarmRule           `json:"alarmRules"`
    LikeDate        string                `json:"likeDate"`
    Sex             string                `json:"sex"`
    Age             int32                 `json:"age"`
    AgeDescription  string                `json:"ageDescription"`
    Race            string                `json:"race"`
    SmileLevel      int32                 `json:"smileLevel"`
    BeautyLevel     int32                 `json:"beautyLevel"`
    FaceFeature     string                `json:"faceFeature"`
    PicSmUrl        []string              `json:"picSmUrl"`
    VideoUrl        string                `json:"videoUrl"`
    AnalyServerId   string                `json:"analyServerId"`
    AnalyServerName string                `json:"analyServerName"`
    AnalyServerIp   string                `json:"analyServerIp"`
    ClusterId       string                `json:"clusterId"`
    LinkId          string                `json:"linkId"`
    DetectScore     float64               `json:"detectScore"`
    IsAlarm         int                   `json:"isAlarm"`
    IsAckAlarm      int                   `json:"isAckAlarm"`
    IsCollect       int                   `json:"isCollect"`
    IsDelete        int                   `json:"isDelete"`
    BaseInfo        []*structure.BaseInfo `json:"baseInfo"`
    TargetInfo      Target
}
type Target struct {
    TargetId       string `json:"targetId"`
    TargetScore    float64 `json:"targetScore"`
    TargetLocation Points
}
type Points struct {
    TopLeft  Point `json:"topLeft"`
    BottomRight Point `json:"bottomRight"`
}
type Point struct {
    Lat float64 `json:"lat"`
    Lon float64 `json:"lon"`
}
//  yolo行为的数据结构
type Personaction struct {
    Id              string      `json:"id"`
@@ -103,6 +109,7 @@
    IsAckAlarm      int         `json:"isAckAlarm"`
    IsCollect       int         `json:"isCollect"`
    IsDelete        int         `json:"isDelete"`
    TargetInfo        []Target
}
type AlarmRule struct {
@@ -110,8 +117,8 @@
    AlarmLevel   string `json:"alarmLevel"`
    RuleText     string `json:"ruleText"`
    DefenceState bool   `json:"defenceState"`
    IsLink         bool    `json:"isLink"`
    LinkInfo     string `json:"linkInfo"`
    IsLink       bool   `json:"isLink"`
    LinkInfo     string `json:"linkInfo"`
}
// 一个face对多个规则组的归置人脸的结构体
@@ -120,46 +127,21 @@
    rules []structure.Result
}
// 往ES插数据
//func InsertToEs(msg ruleserver.ResultMsg) {
//    var timeLabel string
//    // 直接从规则的标签数据里拿符合规则的人脸结果
//    if msg.RuleResult["timeLabel"] != nil {
//        timeLabel = msg.RuleResult["timeLabel"].(string)
//    }
//    logger.Debug("插入数据前看看报警标志位:", timeLabel)
//    if timeLabel == "01" { // 无定时器状态要插入的报警数据
//        InsertFace(msg)
//        flag := ruleserver.BodyIsSame(msg.SdkMessage)
//        if !flag {
//            InsertYolo(msg)
//        }
//    }
//    if timeLabel == "10" { // 定时器状态要插入的首帧报警数据。连带着定时器开启时的那帧
//        InsertFace(msg)
//        InsertYolo(msg)
//    }
//    //if timeLabel == "12" { // 并非报警数据,只是状态改变的数据
//    //    //ChangeStatusFace(msg)
//    //    ChangeStatusYolo(msg)
//    //}
//}
func InsertToEs(msg structure.ResultMsg) {
    InsertFace(msg, "")
    // 如果标签中含有持续时间首次报警的timeLabel的话则不需要过人体追踪,不然就没的插入了
    fk := ruleserver.TrackOrNot(msg.RuleResult)
    if fk {
        InsertYolo(msg, "")
        //if msg.Cid == "61de081a-7ed9-4970-8432-41d642c35456" {
        //    logger.Warn("捕捉188摄像机的持续时间任务.....")
        //    os.Exit(1)
        //}
    } else {
        flag := ruleserver.BodyIsSame(msg.SdkMessage)
        if !flag {
            InsertYolo(msg, "")
    defer func() {
        if err := recover(); err != nil {
            logger.Error("es模块儿的异常捕获:", err)
        }
    }()
    localConfig1, err := cache.GetServerInfo()
    if err != nil {
        panic("配置文件不合法")
    }
    weedfsUrl = "http://" + localConfig1.WebPicIp + ":" + strconv.Itoa(int(localConfig1.WebPicPort)) + "/submit"
    videoPersonUrl = "http://" + localConfig1.AlarmIp + ":" + strconv.Itoa(int(localConfig1.AlarmPort)) + "/" + EsInfo.EsIndex.VideoPersons.IndexName + "/" + EsInfo.EsIndex.VideoPersons.IndexType
    personAction = "http://" + localConfig1.AlarmIp + ":" + strconv.Itoa(int(localConfig1.AlarmPort)) + "/" + EsInfo.EsIndex.Personaction.IndexName + "/" + EsInfo.EsIndex.Personaction.IndexType
    InsertFace(msg, "")
    InsertYolo(msg, "")
}
// 往es中插入人脸数据
@@ -167,10 +149,12 @@
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        logger.Info("往ES插人脸数据")
        faces := []*FaceAndRules{}
        faces = PutFace(faces,msg)
        faces = PutFace(faces, msg)
        //logger.Info("整理后的数据:",faces)
        if faces != nil {
            for _,face := range faces {
            var imgMaxUrl string = ""
            var picTime string = ""
            for _, face := range faces {
                // 上传大图
                // 解压缩并上传图片
                bdata, err := util.UnCompress(msg.Data)
@@ -178,35 +162,29 @@
                    panic("解压缩图片时出现错误")
                }
                alarmRules := []AlarmRule{}
                logger.Warn("人脸id为:",face.Id,"人脸的规则长度为:",len(face.rules))
                //os.Exit(1)
                for _,faceResult := range face.rules {
                for _, faceResult := range face.rules {
                    alarm := ChangeToString(faceResult.DefenceState, faceResult.AlarmLevel)
                    alarmRules = append(alarmRules, AlarmRule{faceResult.RuleGroupId, alarm, faceResult.RuleText, faceResult.DefenceState,faceResult.IsLink,""})
                    alarmRules = append(alarmRules, AlarmRule{faceResult.RuleGroupId, alarm, faceResult.RuleText, faceResult.DefenceState, faceResult.IsLink, ""})
                }
                i := protomsg.Image{}
                err = proto.Unmarshal(bdata, &i)
                bigPhotoUrl := make(map[string]interface{})
                bigPhotoUrl, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                logger.Debug("========大图路径:", bigPhotoUrl)
                // 人脸检测,没有相似的底库人员
                localConfig, err := cache.GetServerInfo()
                if err != nil {
                    logger.Error("查询本机信息失败!")
                }
                serverIp, err := GetLocalIP()
                // 查询cameraName
                camera, err := cache.GetCameraById(msg.Cid)
                if err != nil {
                    logger.Error("查询摄像机信息失败")
                }
                // 先传小图,再传大图,防止脸上有线
                bytes := util.SubImg(i, int(face.Location.X), int(face.Location.Y), int(face.Location.X+face.Location.Width), int(face.Location.Y+face.Location.Height))
                resp, err := util.PostFormBufferData1(weedfsUrl, bytes, uuid.NewV4().String())
                if err != nil {
                    logger.Error("上传小图出错")
                }
                //logger.Info("================小图地址:", resp["fileUrl"].(string))
                // 上传大图
                if imgMaxUrl == "" {
                    bigPhotoUrl := make(map[string]interface{})
                    bigPhotoUrl, err = util.DrawPolygonOnImageForFace(msg.Cid, i, msg.RuleResult["face"].([]structure.FaceResult), weedfsUrl)
                    logger.Debug("========大图路径:", bigPhotoUrl)
                    imgMaxUrl = bigPhotoUrl["fileUrl"].(string)
                    picTime = i.Timestamp
                }
                sex := ""
                logger.Info(sex)
                if face.ThftRes.Gender == 1 {
                    sex = "男"
                } else {
@@ -214,35 +192,42 @@
                }
                race := getRaceString(face.ThftRes.Race)
                ageDescription := getDescription(face.ThftRes.Age)
                esDataId := uuid.NewV4().String()
                logger.Info(ageDescription)
                //esDataId := uuid.NewV4().String()
                linksId := ""
                if linkId != "" {
                    linksId = linkId
                }
                var target = new(Target)
                target.TargetId = strconv.FormatUint(face.Id, 10)
                target.TargetScore = face.Score
                target.TargetLocation = Points{TopLeft:Point{face.Location.X,face.Location.Y},BottomRight:Point{face.Location.X+face.Location.Width,face.Location.Y+face.Location.Height}}
                //logger.Info("人脸的id:",strconv.FormatUint(face.Id, 10))
                pervideo := PerVideoPicture{
                    esDataId,
                    msg.Push.PushId,
                    msg.Cid,
                    camera.Addr,
                    i.Timestamp,
                    bigPhotoUrl["fileUrl"].(string),
                    msg.Push.Cam.Addr,
                    picTime,
                    imgMaxUrl,
                    msg.Tasklab.Taskid,
                    msg.Tasklab.Taskname,
                    "人脸",
                    "",
                    alarmRules,
                    time.Now().Format("2006-01-02 15:04:05"), // 只检测,没有比对时间
                    sex,
                    sex,                                      //暂改为人脸id strconv.FormatUint(face.Id, 10)
                    face.ThftRes.Age,
                    ageDescription,
                    ageDescription, // 暂改为分值fmt.Sprintf("%.2f",face.Score)
                    race,
                    face.ThftRes.Smile,
                    face.ThftRes.Beauty,
                    base64.StdEncoding.EncodeToString(face.Feature),
                    []string{resp["fileUrl"].(string)},
                    "暂无集群",
                    localConfig.ServerId,
                    localConfig.ServerName,
                    serverIp,
                    "",
                    msg.Push.ServerId,
                    msg.Push.ServerName,
                    msg.Push.LocalIp,
                    "",
                    linksId,
                    face.Score,
@@ -251,6 +236,7 @@
                    0,
                    0,
                    face.Liker,
                    *target,
                }
                requstbody, err := json.Marshal(pervideo)
@@ -264,7 +250,7 @@
                } else {
                    logger.Info("插入es返回的信息:", resp1)
                    // 发出录像信号
                    ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: esDataId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, ImgId: i.Id, SdkIds: []string{}, Type: 1})
                    ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, VideoUrl:msg.Push.VideoUrl,ImgId: i.Id, SdkIds: []string{}, Type: 1})
                }
            }
        }
@@ -272,7 +258,7 @@
}
// 归置人脸
func PutFace(faces []*FaceAndRules,msg structure.ResultMsg)[]*FaceAndRules{
func PutFace(faces []*FaceAndRules, msg structure.ResultMsg) []*FaceAndRules {
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        for _, faceResult := range msg.RuleResult["face"].([]structure.FaceResult) {
            faces = hebingFace(faces, faceResult)
@@ -282,28 +268,28 @@
        return nil
    }
}
func hebingFace(faces []*FaceAndRules, faceResult structure.FaceResult) []*FaceAndRules{
func hebingFace(faces []*FaceAndRules, faceResult structure.FaceResult) []*FaceAndRules {
    for _, arg := range faceResult.Args {
        // 拿到每一张人脸
        logger.Info("归置人脸时相似者的数量:",len(arg.Liker))
        //logger.Info("归置人脸时相似者的数量:", len(arg.Liker))
        flag := false
        for _, face := range faces {
            for _,lik := range face.Liker {
                logger.Warn("--------合并人脸时相似者:",lik.PersonId,lik.TableName)
            }
            //for _, lik := range face.Liker {
            //    //logger.Warn("--------合并人脸时相似者:", lik.PersonId, lik.TableName)
            //}
            if arg.Id == face.Id {
                flag = true
                face.rules = append(face.rules,faceResult.Result)
                face.rules = append(face.rules, faceResult.Result)
                // 相似者去重归并
                for _,liker := range arg.Liker {
                for _, liker := range arg.Liker {
                    flag1 := true
                    for _,liker1 := range face.Liker {
                    for _, liker1 := range face.Liker {
                        if liker.PersonId == liker1.PersonId {
                            flag1 = false
                        }
                    }
                    if flag1 {
                        face.Liker = append(face.Liker,liker)
                        face.Liker = append(face.Liker, liker)
                    }
                }
                //face.Liker = append(face.Liker,arg.Liker...)
@@ -331,6 +317,7 @@
            logger.Info("往ES插yolo数据")
            var sdkNames string = ""
            alarmRules := []AlarmRule{}
            var targetInfos []Target
            url := []string{}
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10" {
@@ -342,7 +329,7 @@
                    if yoloResult.IsLink {
                        linkInfo = "联动任务"
                    }
                    alarmRules = append(alarmRules, AlarmRule{yoloResult.RuleGroupId, alarm, yoloResult.RuleText, yoloResult.DefenceState,yoloResult.IsLink,linkInfo})
                    alarmRules = append(alarmRules, AlarmRule{yoloResult.RuleGroupId, alarm, yoloResult.RuleText, yoloResult.DefenceState, yoloResult.IsLink, linkInfo})
                    // 上传缓存数据的图片拿到url
                    if yoloResult.Others.CacheData != nil {
                        //InsertYolo(msg.RuleResult["cacheData"].(ruleserver.ResultMsg))
@@ -356,13 +343,33 @@
                            }
                            i := protomsg.Image{}
                            err = proto.Unmarshal(bdata, &i)
                            resp1, err1 := util.DrawPolygonOnImage(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            resp1, err1 := util.DrawPolygonOnImageForYolo(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            if err1 != nil {
                                logger.Error("缓存数据画框或上传图片服务器出错", err)
                            } else {
                                logger.Info("上传的图片信息:", resp1)
                            }
                            url = append(url, resp1["fileUrl"].(string))
                            if resp1["fileUrl"] != nil {
                                url = append(url, resp1["fileUrl"].(string))
                            }
                        }
                    }
                    // 装配目标信息数据
                    for _,target := range yoloResult.Location  {
                        // 去重添加
                        var flag = true
                        for _,selectTarget := range targetInfos  {
                            if strconv.FormatUint(target.TargetId, 10) == selectTarget.TargetId {
                                flag = false
                                break
                            }
                        }
                        if flag {
                            var target1 = new(Target)
                            target1.TargetId = strconv.FormatUint(target.TargetId, 10)
                            target1.TargetScore = target.TargetScore
                            target1.TargetLocation = Points{TopLeft:Point{target.X,target.Y},BottomRight:Point{target.X+target.Width,target.Y+target.Height}}
                            targetInfos = append(targetInfos,*target1)
                        }
                    }
                }
@@ -397,7 +404,7 @@
            if len(alarmRules) > 0 {
                isAlarm = 1
                //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                resp, err = util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                resp, err = util.DrawPolygonOnImageForYolo(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                if err != nil {
                    logger.Error("画框或上传图片服务器出错", err)
                    return
@@ -409,38 +416,26 @@
                // 不是报警数据不存
                return
            }
            // logger.Println("图片上传返回值:", resp)
            // 查询本机信息
            localConfig, err := cache.GetServerInfo()
            if err != nil {
                logger.Error("查询本机信息失败!")
            }
            // 查询cameraName
            camera, err := cache.GetCameraById(msg.Cid)
            if err != nil {
                logger.Error("查询摄像机信息失败")
            }
            serverIp, err := GetLocalIP()
            if resp["fileUrl"] != nil {
                url = append(url, resp["fileUrl"].(string))
                esDataId := uuid.NewV4().String()
                //esDataId := uuid.NewV4().String()
                linksId := ""
                if linkId != "" {
                    linksId = linkId
                }
                peraction := Personaction{
                    esDataId,
                    msg.Push.PushId,
                    msg.Cid,
                    camera.Name,
                    camera.Addr,
                    msg.Push.Cam.Name,
                    msg.Push.Cam.Addr,
                    msg.Tasklab.Taskid,
                    msg.Tasklab.Taskname,
                    sdkNames,
                    "",
                    alarmRules,
                    localConfig.ServerId,
                    localConfig.ServerName,
                    serverIp,
                    msg.Push.ServerId,
                    msg.Push.ServerName,
                    msg.Push.LocalIp,
                    "",
                    url,
                    i.Timestamp,
@@ -450,13 +445,13 @@
                    0,
                    0,
                    0,
                    targetInfos,
                }
                requstbody, err := json.Marshal(peraction)
                if err != nil {
                    logger.Info("json parse error ", err)
                    return
                }
                resp1, err2 := EsReq("POST", personAction, requstbody)
                if err2 != nil {
@@ -464,7 +459,7 @@
                } else {
                    logger.Debug("插入es返回的数据信息是:", resp1)
                    // 发出录像信号
                    ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: esDataId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, ImgId: i.Id, SdkIds: []string{}, Type: 2})
                    ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid,VideoUrl:msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{}, Type: 2})
                    logger.Warn("__________________________________________往ES插入yolo数据成功")
                    //os.Exit(1)
                }
@@ -473,155 +468,6 @@
            logger.Debug("timeLabel条件都不符合!")
        }
    }
}
func ChangeStatusYolo(msg structure.ResultMsg) {
    logger.Info("往ES插yolo非报警状态改变数据")
    var sdkNames string = ""
    alarmRules := []AlarmRule{}
    bdata, err := util.UnCompress(msg.Data)
    if err != nil {
        panic("解压缩图片时出现错误")
    }
    i := protomsg.Image{}
    err = proto.Unmarshal(bdata, &i)
    //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
    resp, err := util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
    if err != nil {
        logger.Error("画框或上传图片服务器出错", err)
    } else {
        logger.Info("上传的图片信息:", resp)
    }
    // logger.Println("图片上传返回值:", resp)
    // 查询本机信息
    localConfig, err := cache.GetServerInfo()
    if err != nil {
        logger.Error("查询本机信息失败!")
    }
    // 查询cameraName
    camera, err := cache.GetCameraById(msg.Cid)
    if err != nil {
        logger.Error("查询摄像机信息失败")
    }
    serverIp, err := GetLocalIP()
    esDataId := uuid.NewV4().String()
    peraction := Personaction{
        esDataId,
        msg.Cid,
        camera.Name,
        camera.Addr,
        msg.Tasklab.Taskid,
        msg.Tasklab.Taskname,
        sdkNames,
        "yolo非报警状态改变数据",
        alarmRules,
        localConfig.ServerId,
        localConfig.ServerName,
        serverIp,
        "",
        []string{resp["fileUrl"].(string)},
        i.Timestamp,
        "",
        "",
        0,
        0,
        0,
        0,
    }
    requstbody, err := json.Marshal(peraction)
    if err != nil {
        logger.Info("json parse error ", err)
        return
    }
    resp1, err1 := EsReq("POST", personAction, requstbody)
    if err1 != nil {
        logger.Error("往ES插入数据失败", err)
    } else {
        logger.Info("插入es返回的信息:", resp1)
        // 发出录像信号
        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: esDataId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, ImgId: i.Id, SdkIds: []string{}, Type: 2})
        logger.Warn("__________________________________________往ES插入yolo数据成功")
        //os.Exit(1)
    }
}
func ChangeStatusFace(msg structure.ResultMsg) {
    logger.Info("往ES插入人脸非报警但是状态转换数据")
    // 上传大图
    // 解压缩并上传图片
    bdata, err := util.UnCompress(msg.Data)
    if err != nil {
        panic("解压缩图片时出现错误")
    }
    i := protomsg.Image{}
    err = proto.Unmarshal(bdata, &i)
    bigPhotoUrl := make(map[string]interface{})
    bigPhotoUrl, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
    logger.Debug("========大图路径:", bigPhotoUrl)
    // 人脸检测,没有相似的底库人员
    localConfig, err := cache.GetServerInfo()
    if err != nil {
        logger.Error("查询本机信息失败!")
    }
    serverIp, err := GetLocalIP()
    // 查询cameraName
    camera, err := cache.GetCameraById(msg.Cid)
    if err != nil {
        logger.Error("查询摄像机信息失败")
    }
    esDataId := uuid.NewV4().String()
    pervideo := PerVideoPicture{
        esDataId,
        msg.Cid,
        camera.Addr,
        i.Timestamp,
        bigPhotoUrl["fileUrl"].(string),
        msg.Tasklab.Taskid,
        msg.Tasklab.Taskname,
        "人脸",
        "状态转换数据,非报警数据",
        []AlarmRule{},
        time.Now().Format("2006-01-02 15:04:05"), // 只检测,没有比对时间
        "",
        0,
        "",
        "",
        0,
        0,
        "",
        []string{""},
        "暂无集群",
        localConfig.ServerId,
        localConfig.ServerName,
        serverIp,
        "",
        "",
        0,
        1,
        0,
        0,
        0,
        []*structure.BaseInfo{},
    }
    requstbody, err := json.Marshal(pervideo)
    if err != nil {
        logger.Info("json parse error ", err)
        return
    }
    resp1, err1 := EsReq("POST", videoPersonUrl, requstbody)
    if err1 != nil {
        logger.Error("上传ES出错!---", err1)
    } else {
        logger.Info("插入es返回的信息:", resp1)
        // 发出录像信号
        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: esDataId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, ImgId: i.Id, SdkIds: []string{}, Type: 1})
    }
    //if msg.RuleResult["cacheData"] != nil {
    //    InsertFace(msg.RuleResult["cacheData"].(ruleserver.ResultMsg))
    //}
}
// 获取本机ip
@@ -706,100 +552,3 @@
    }
    return race
}
//for _, faceResult := range msg.RuleResult["face"].([]ruleserver.FaceResult) {
//    for _, face := range faceResult.Args {
//        // 上传大图
//        // 解压缩并上传图片
//        bdata, err := util.UnCompress(msg.Data)
//        if err != nil {
//            panic("解压缩图片时出现错误")
//        }
//        alarmRules := []AlarmRule{}
//        alarm := ChangeToString(faceResult.DefenceState, faceResult.AlarmLevel)
//        alarmRules = append(alarmRules, AlarmRule{faceResult.RuleGroupId, alarm, faceResult.RuleText, faceResult.DefenceState})
//        i := protomsg.Image{}
//        err = proto.Unmarshal(bdata, &i)
//        bigPhotoUrl := make(map[string]interface{})
//        bigPhotoUrl, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
//        logger.Debug("========大图路径:", bigPhotoUrl)
//        // 人脸检测,没有相似的底库人员
//        localConfig, err := cache.GetServerInfo()
//        if err != nil {
//            logger.Error("查询本机信息失败!")
//        }
//        serverIp, err := GetLocalIP()
//        // 查询cameraName
//        camera, err := cache.GetCameraById(msg.Cid)
//        if err != nil {
//            logger.Error("查询摄像机信息失败")
//        }
//        bytes := util.SubImg(i, int(face.Location.X), int(face.Location.Y), int(face.Location.X+face.Location.Width), int(face.Location.Y+face.Location.Height))
//        resp, err := util.PostFormBufferData1(weedfsUrl, bytes, uuid.NewV4().String())
//        if err != nil {
//            logger.Error("上传小图出错")
//        }
//        logger.Info("================小图地址:", resp["fileUrl"].(string))
//        sex := ""
//        if face.ThftRes.Gender == 1 {
//            sex = "男"
//        } else {
//            sex = "女"
//        }
//        race := getRaceString(face.ThftRes.Race)
//        ageDescription := getDescription(face.ThftRes.Age)
//        esDataId := uuid.NewV4().String()
//        linksId := ""
//        if linkId != "" {
//            linksId = linkId
//        }
//        pervideo := PerVideoPicture{
//            esDataId,
//            msg.Cid,
//            camera.Addr,
//            i.Timestamp,
//            strings.Split(bigPhotoUrl["fileUrl"].(string), "/")[1],
//            msg.Tasklab.Taskid,
//            msg.Tasklab.Taskname,
//            "人脸",
//            "",
//            alarmRules,
//            time.Now().Format("2006-01-02 15:04:05"), // 只检测,没有比对时间
//            sex,
//            face.ThftRes.Age,
//            ageDescription,
//            race,
//            face.ThftRes.Smile,
//            face.ThftRes.Beauty,
//            base64.StdEncoding.EncodeToString(face.Feature),
//            []string{strings.Split(resp["fileUrl"].(string), "/")[1]},
//            "暂无集群",
//            localConfig.ServerId,
//            localConfig.ServerName,
//            serverIp,
//            "",
//            linksId,
//            face.Score,
//            1,
//            0,
//            0,
//            0,
//            face.Liker,
//        }
//        requstbody, err := json.Marshal(pervideo)
//
//        if err != nil {
//            logger.Info("json parse error ", err)
//            return
//        }
//        resp1, err1 := EsReq("POST", videoPersonUrl, requstbody)
//        if err1 != nil {
//            logger.Error("上传ES出错!---", err1)
//        } else {
//            logger.Info("插入es返回的信息:", resp1)
//            // 发出录像信号
//            ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: esDataId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, ImgId: i.Id, SdkIds: []string{}, Type: 1})
//        }
//    }
//}
labelFilter/readyDataForLabel.go
@@ -1,8 +1,8 @@
package labelFilter
import (
    "basic.com/valib/logger.git"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "time"
)
@@ -20,29 +20,41 @@
func (label *Label)DataFormatToLabel(result structure.ResultMsg) {
    logger.Debug("face结果:",result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0)
    logger.Debug("yolo结果:",result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0) {
        logger.Info("---------------标签过滤器赋值")
        label.CameraId = result.Cid
        camera, err := cache.GetCameraById(result.Cid)
        if err != nil {
            logger.Error("查询摄像机信息出错")
        }
        label.CameraName = camera.Name
        label.CameraAddr = camera.Addr
        label.TaskId = result.Tasklab.Taskid
        label.Time = time.Now().Format("2006-01-02 15:04:05")
        if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0 {
            for _,faceGroup := range result.RuleResult["face"].([]structure.FaceResult) {
                label.Persons = append(label.Persons,faceGroup)
                label.DefenceLevel = append(label.DefenceLevel,faceGroup.AlarmLevel)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0) { // 得有人脸或者yolo规则才可以
        // 先判断一下数据带的规则标签是否有报警的可以推送的
        flag := false
        for _, res := range result.RuleResult["yolo"].([]structure.Result) {
            //logger.Info("定时器打的数字标签:",res.Others.TimeLabel)
            if res.Others.TimeLabel == "01" || res.Others.TimeLabel == "10" {
                flag = true
            }
        }
        if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0 {
            for _,yoloGroup := range result.RuleResult["yolo"].([]structure.Result) {
                label.DefenceLevel = append(label.DefenceLevel,yoloGroup.AlarmLevel)
        if flag || (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0){
            logger.Info("---------------标签过滤器赋值")
            label.CameraId = result.Cid
            camera, err := cache.GetCameraById(result.Cid)
            if err != nil {
                logger.Error("查询摄像机信息出错")
            }
            label.CameraName = camera.Name
            label.CameraAddr = camera.Addr
            label.TaskId = result.Tasklab.Taskid
            label.Time = time.Now().Format("2006-01-02 15:04:05")
            if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0 {
                for _,faceGroup := range result.RuleResult["face"].([]structure.FaceResult) {
                    label.Persons = append(label.Persons,faceGroup)
                    label.DefenceLevel = append(label.DefenceLevel,faceGroup.AlarmLevel)
                }
            }
            if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0 {
                for _,yoloGroup := range result.RuleResult["yolo"].([]structure.Result) {
                    label.DefenceLevel = append(label.DefenceLevel,yoloGroup.AlarmLevel)
                }
            }
            logger.Info("------------标签过滤器赋值完毕")
        }
        logger.Info("------------标签过滤器赋值完毕")
    }
}
labelFilter/req.go
@@ -1,22 +1,29 @@
package labelFilter
import (
    "basic.com/dbapi.git"
    "basic.com/valib/logger.git"
    "fmt"
    "github.com/golang/protobuf/proto"
    "nanomsg.org/go-mangos"
    "nanomsg.org/go-mangos/protocol/rep"
    "nanomsg.org/go-mangos/protocol/req"
    "nanomsg.org/go-mangos/transport/ipc"
    "nanomsg.org/go-mangos/transport/tcp"
    "os"
    "github.com/golang/protobuf/proto"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "time"
)
var urlPool = make(map[string]chan []byte,100)
//var urlChans = make([]urlChan,100)
//type urlChan struct {
//    url string
//    ch chan *structure.ResultMsg
//}
//var pool chan *structure.ResultMsg = make(chan *structure.ResultMsg)
func Die(format string, v ...interface{}) {
    logger.Info("+++++++",format)
    os.Exit(1)
    logger.Info("+++++++",format,v)
    //os.Exit(1)
}
func date() string {
@@ -53,42 +60,109 @@
    }
}
func Push(url string,data ruleserver.ResultMsg) {
    var sock mangos.Socket
func Init(){
    var api dbapi.EventPushApi
    b, allRules := api.FindAllDetails()
    logger.Info("初始化事件推送,查看所有规则组:", allRules)
    if !b {
        logger.Error("查询时间推送规则失败!")
    }
    for _, ruleGroup := range allRules {
        if ruleGroup.Enable { // 大规则开关开启状态
            for _, url := range ruleGroup.Urls {
                // 为每个url建立一个chan
                if urlPool[url.Url] == nil {
                    urlPool[url.Url] = make(chan []byte,100)
                    logger.Info("初始化信息:",urlPool)
                    go GoPush(url.Url)
                }
            }
        }
    }
}
func GoPush(url string) {
    var err error
    var msg []byte
    var sock mangos.Socket
    if sock, err = req.NewSocket(); err != nil {
        Die("创建请求socket失败: %s", err.Error())
    }
    errSize := sock.SetOption(mangos.OptionMaxRecvSize,5*1024*1024)
    errSize := sock.SetOption(mangos.OptionMaxRecvSize,30*1024*1024)
    if errSize != nil {
        fmt.Errorf("Failed set MaxRecvSize: %v", err)
        logger.Error("传输的数据超过大小限制")
        return
    }
    //sock.AddTransport(ipc.NewTransport())
    errTimeOut := sock.SetOption(mangos.OptionRecvDeadline,time.Millisecond * 1500)
    if errTimeOut != nil {
        logger.Error("接收响应超时")
        return
    }
    errTimeOut1 := sock.SetOption(mangos.OptionSendDeadline,time.Millisecond * 1500)
    if errTimeOut1 != nil {
        logger.Error("发送超时")
        return
    }
    errWrite := sock.SetOption(mangos.OptionWriteQLen,5)
    if errWrite != nil {
        logger.Error("设置传输缓存大小失败")
        return
    }
    errRead := sock.SetOption(mangos.OptionReadQLen,5)
    if errRead != nil {
        logger.Error("设置传输缓存大小失败")
        return
    }
    sock.AddTransport(tcp.NewTransport())
    if err = sock.Dial(url); err != nil {
        Die("请求socket拨号失败: %s", err.Error())
    if err = sock.Dial("tcp://"+url); err != nil {
        logger.Error("请求socket拨号失败: ", err.Error())
    }
    logger.Info("序列化数据")
    bytes,err1 := proto.Marshal(data)
    logger.Info("数据长度为:",len(bytes))
    if err1 != nil {
        logger.Info("序列化失败:",err1)
    //for v := range pool{
    //    logger.Info("无限循环",v.Cid)
    //}
    //var ch chan *structure.ResultMsg
    //for _, v := range urlChans  {
    //    if v.url == url{
    //        ch = v.ch
    //    }
    //}
    logger.Info("chan信息:",urlPool[url])
    for {
        select {
        // case <-ctx.Done():
        //     return
        case data := <- urlPool[url]:
            //logger.Info("接收到数据",data.Cid)
            //bytes,err1 := proto.Marshal(data)
            go func(data []byte) {
                logger.Info("数据长度为:",len(data))
                //if err1 != nil {
                //    logger.Info("序列化失败:",err1)
                //}
                start := time.Now()
                logger.Debug("groutine"+url+"推送数据")
                //bytes := []byte("ndfasojdfaidsos")
                if err = sock.Send(data); err != nil {
                    Die("groutine"+url+"推送socket发送数据失败: ", err.Error())
                }
                pushTime := time.Since(start)
                msg, err = sock.Recv();
                if err != nil {
                    Die("groutine"+url+"接收响应失败: ", err.Error(),pushTime,time.Since(start))
                } else {
                    logger.Debug("事件推送成功!groutine"+url+"收到响应",string(msg),pushTime,time.Since(start))
                }
            }(data)
        default:
        }
    }
    logger.Debug("推送数据")
    //bytes := []byte("ndfasojdfaidsos")
    if err = sock.Send(bytes); err != nil {
        Die("推送socket发送数据失败: %s", err.Error())
    }
    if msg, err = sock.Recv(); err != nil {
        Die("接收响应失败: %s", err.Error())
    }
    logger.Debug("数据推送成功!收到响应",string(msg))
    sock.Close()
}
//func main() {
//    url := "tcp://192.168.1.123:40011"
//    Push(url,"hahahaha")
labelFilter/ruleForLabel.go
@@ -3,18 +3,25 @@
import (
    "basic.com/dbapi.git"
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/golang/protobuf/proto"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
    "time"
)
func Judge(msg structure.ResultMsg) {
func PushSomthing(msg structure.ResultMsg) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("事件推送模块儿的异常捕获:",err)
        }
    }()
    start := time.Now()
    // 装配成自己可以识别的数据
    label := new(Label)
    label.DataFormatToLabel(msg)
    logger.Info("label的信息:", label.CameraName, label.DefenceLevel, label.Time)
    //logger.Info("label的信息:", label.CameraName, label.DefenceLevel, label.Time)
    if label.CameraName == "" {
        logger.Error("无效数据,直接返回")
        return
@@ -22,7 +29,7 @@
    //拿到所有规则组
    var api dbapi.EventPushApi
    b, allRules := api.FindAllDetails()
    logger.Info("查看所有规则组:", allRules)
    //logger.Info("查看所有规则组:", allRules)
    if !b {
        logger.Error("查询时间推送规则失败!")
    }
@@ -33,7 +40,7 @@
            timeFlag := timeJudge(label, ruleGroup)
            if !timeFlag {
                logger.Info("不在规则的时间范围内,不推送!")
                return
                continue
            }
            result := ""
            var Connector string
@@ -77,6 +84,7 @@
                    logger.Info("通过规则,表达式为:", result)
                    // 推送服务器
                    pushData(ruleGroup.Urls, msg)
                    logger.Info("时间推送所用时间:",time.Since(start))
                    //os.Exit(1)
                } else {
                    logger.Info("没通过规则,表达式为:", result)
@@ -92,7 +100,7 @@
// 是否符合时间规则
func timeJudge(label *Label, groupRule protomsg.EventPush) bool {
    timeNow := time.Now().Format("2006-01-02 15:04:05")
    logger.Info("标签过滤器起始时间为:",groupRule.TimeStart,groupRule.TimeEnd)
    //logger.Info("标签过滤器起始时间为:",groupRule.TimeStart,groupRule.TimeEnd)
    flag1 := isBefore(groupRule.TimeStart, timeNow)
    flag2 := isBefore(timeNow, groupRule.TimeEnd)
    if flag1 && flag2 {
@@ -129,7 +137,7 @@
    if rule.TopicArg == "addr" {
        formula = "'" + label.CameraAddr + "'" + rule.Operator + "'" + rule.RuleValue + "'"
    }
    logger.Info("-------打印摄像机规则公式:",formula)
    //logger.Info("-------打印摄像机规则公式:",formula)
    expression, err := govaluate.NewEvaluableExpression(formula);
    if err != nil {
        logger.Error("表达式有误,请检查!", formula)
@@ -144,7 +152,7 @@
        logger.Info("符合摄像机规则!")
        return "true"
    }
    logger.Info("不符合摄像机规则!")
    //logger.Info("不符合摄像机规则!")
    return "false"
}
@@ -166,7 +174,7 @@
                for _, liker := range arg.Liker {
                    formula := "'" + liker.TableId + "'" + rule.Operator + "'" + rule.RuleValue + "'"
                    expression, err := govaluate.NewEvaluableExpression(formula);
                    logger.Info("-------打印底库规则公式:",formula)
                    //logger.Info("-------打印底库规则公式:",formula)
                    if err != nil {
                        logger.Error("表达式有误,请检查!", formula)
                        return "false"
@@ -206,7 +214,7 @@
                // 其他这个值先这么处理
                return "true"
            }
            logger.Info("-------打印人员规则公式:",formula)
            //logger.Info("-------打印人员规则公式:",formula)
            expression, err := govaluate.NewEvaluableExpression(formula);
            if err != nil {
                logger.Error("表达式有误,请检查!", formula)
@@ -230,7 +238,7 @@
                }
            } else {
                formula := strconv.Itoa(int(personGroup.AlarmLevel)) + rule.Operator + formate(rule.RuleValue)
                logger.Info("-------打印人员等级规则公式:",formula)
                //logger.Info("-------打印人员等级规则公式:",formula)
                expression, err := govaluate.NewEvaluableExpression(formula);
                if err != nil {
                    logger.Error("表达式有误,请检查!", formula)
@@ -267,7 +275,7 @@
    } else {
        for _, def := range label.DefenceLevel {
            formula := strconv.Itoa(int(def)) + rule.Operator + rule.RuleValue
            logger.Info("-------打印布防等级规则公式:",formula)
            //logger.Info("-------打印布防等级规则公式:",formula)
            expression, err := govaluate.NewEvaluableExpression(formula);
            if err != nil {
                logger.Error("表达式有误,请检查!", formula)
@@ -292,7 +300,7 @@
func taskJudge(label *Label, rule *protomsg.EventPushRule) string {
    formula := "'"+label.TaskId +"'"+ rule.Operator +"'"+ rule.RuleValue+"'"
    expression, err := govaluate.NewEvaluableExpression(formula);
    logger.Info("-------打印任务规则公式:",formula)
    //logger.Info("-------打印任务规则公式:",formula)
    if err != nil {
        logger.Error("表达式有误,请检查!", formula)
        return "false"
@@ -314,8 +322,18 @@
func pushData(urls []*protomsg.PushUrl, data structure.ResultMsg) {
    for _, url := range urls {
        logger.Debug("看看推送地址:",url.Url)
        Push("tcp://192.168.1.123:40012", data)
        bytes,err1 := proto.Marshal(data)
        if err1 != nil {
            logger.Info("序列化失败:",err1)
        }
        if _, ok := urlPool[url.Url] ; ok {
            urlPool[url.Url] <- bytes
            logger.Info("chan信息而: ", urlPool[url.Url])
        }
        logger.Info("chan信息以: ", urlPool[url.Url])
    }
}
// 把报警等级转化成汉字
logger/logger.go
@@ -17,47 +17,47 @@
    InfoLevel
    DebugLevel
)
var loggerString string = ""
const (
    color_red = uint8(iota + 91)
    color_green        //    绿
    color_yellow        //    黄
    color_blue            //     蓝
    color_magenta         //    洋红
    color_green        //    绿
    color_yellow        //    黄
    color_blue            //     蓝
    color_magenta         //    洋红
)
const (
    fatalPrefix        =    "[FATAL] "
    errorPrefix        =    "[ERROR] "
    warnPrefix        =    "[WARN] "
    infoPrefix        =    "[INFO] "
    debugPrefix        =    "[DEBUG] "
    fatalPrefix        =    "[FATAL] "
    errorPrefix        =    "[ERROR] "
    warnPrefix        =    "[WARN] "
    infoPrefix        =    "[INFO] "
    debugPrefix        =    "[DEBUG] "
)
const (
    ByDay    int = iota
    ByDay    int = iota
    ByWeek
    ByMonth
    BySize
)
type LogFile struct {
    level    int        // 日志等级
    saveMode int        // 保存模式
    saveDays int        // 日志保存天数
    logTime  int64        //
    fileName string        // 日志文件名
    filesize int64        // 文件大小, 需要设置 saveMode 为 BySize 生效
    level    int        // 日志等级
    saveMode int        // 保存模式
    saveDays int        // 日志保存天数
    logTime  int64        //
    fileName string        // 日志文件名
    filesize int64        // 文件大小, 需要设置 saveMode 为 BySize 生效
    fileFd   *os.File
}
var logFile LogFile
func init()  {
    logFile.saveMode = ByDay    // 默认按天保存
    logFile.saveDays = 7        // 默认保存三天的
    logFile.saveMode = ByDay    // 默认按天保存
    logFile.saveDays = 7        // 默认保存三天的
    logFile.level = DebugLevel
    //logFile.filesize = 1024 * 1024 * 10    // 默认10M, 需要设置 saveMode 为 BySize
    //logFile.filesize = 1024 * 1024 * 10    // 默认10M, 需要设置 saveMode 为 BySize
}
func Config(logFolder string, level int) {
@@ -92,6 +92,7 @@
    if logFile.level >= DebugLevel {
        log.SetPrefix(blue(debugPrefix))
        _ = log.Output(2, fmt.Sprintln(args...))
        //loggerString += fmt.Sprintln(args...)
    }
}
@@ -99,6 +100,7 @@
    if logFile.level >= InfoLevel {
        log.SetPrefix(green(infoPrefix))
        _ = log.Output(2, fmt.Sprintln(args...))
        //loggerString += fmt.Sprintln(args...)
    }
}
@@ -106,6 +108,7 @@
    if logFile.level >= WarnLevel {
        log.SetPrefix(magenta(warnPrefix))
        _ = log.Output(2, fmt.Sprintln(args...))
        //loggerString += fmt.Sprintln(args...)
    }
}
@@ -113,6 +116,7 @@
    if logFile.level >= ErrorLevel {
        log.SetPrefix(red(errorPrefix))
        _ = log.Output(2, fmt.Sprintln(args...))
        //loggerString += fmt.Sprintln(args...)
    }
}
@@ -120,7 +124,11 @@
    if logFile.level >= FatalLevel {
        log.SetPrefix(red(fatalPrefix))
        _ = log.Output(2, fmt.Sprintln(args...))
        //loggerString += fmt.Sprintln(args...)
    }
}
func OutPutByPanlei() {
    _ = log.Output(2, loggerString)
}
func GetRedPrefix(s string) string {
@@ -167,7 +175,7 @@
                logFile.logTime = time.Now().Unix()
            }
        }
    default:    // 默认按天  ByDay
    default:    // 默认按天  ByDay
        if logFile.logTime+3600 < time.Now().Unix() {
            logFile.createLogFile()
            logFile.logTime = time.Now().Unix()
main.go
@@ -7,23 +7,20 @@
    "net/http"
    _ "net/http/pprof"
    "ruleprocess/insertdata"
    "ruleprocess/labelFilter"
    "ruleprocess/structure"
    "ruleprocess/util"
    "time"
    //"bufio"
    //"bytes"
    "basic.com/valib/logger.git"
    "flag"
    "fmt"
    "github.com/golang/protobuf/proto"
    "ruleprocess/logger"
    //"gocv.io/x/gocv"
    //"image"
    //"image/color"
    //"os"
    "ruleprocess/cache"
    "ruleprocess/ruleserver"
    "sync"
    "github.com/spf13/viper"
)
var dbIp = flag.String("dbIp", "127.0.0.1", "dbserver ip")
@@ -31,12 +28,22 @@
var surveyPort = flag.Int("surveyPort", 40007, "survey port") //心跳
var pubPort = flag.Int("pubPort", 50007, "pubsub port")       //数据更新
var initchan = make(chan bool)
var env =  flag.String("env","pro","env set")
func init() {
    flag.Parse()
    // 日志初始化
    logger.Config("./info.log", logger.DebugLevel)
    logger.Info("日志初始化成功!")
    insertdata.Init(*env)
    var logFile = "./logger/"
    if viper.GetString("LogBasePath") != "" {
        logFile = viper.GetString("LogBasePath")
    }
    logFile = logFile + "ruleprocess.log"
    fmt.Println("日志地址:",logFile)
    logger.Config(logFile, logger.DebugLevel)
    logger.SetSaveDays(7)
    logger.Info("日志初始化成功!")
}
func main() {
    //fmt.Println("缓存初始化完成",<- initchan)//dbserver初始化完毕
@@ -51,6 +58,7 @@
    go cache.Init(initchan, *dbIp, *surveyPort, *pubPort)
    logger.Info("cache init completed!!!", <-initchan) //dbserver初始化完毕
    ruleserver.Init()
    labelFilter.Init()
    go ruleserver.TimeTicker()
    go ruleserver.StartServer()
    nReciever("ipc:///tmp/sdk-2-rules-process.ipc", deliver.PushPull, 1)
@@ -90,12 +98,15 @@
                    ruleserver.Judge(&arg, &m) // 把sdkMessage传进去,方便缓存数据时拼出一个resultMag
                    // 把arg里的打的标签拿出来给m再封装一层
                    resultMsg := structure.ResultMsg{SdkMessage: &m, RuleResult: arg.RuleResult}
                    logger.Debug("规则判断完所用时间:", time.Since(start))
                    ruleserver.GetAttachInfo(resultMsg.SdkMessage)
                    ruleEnd := time.Since(start)
                    logger.Debug("规则判断完所用时间:", ruleEnd)
                    // 将打完标签的数据插入到ES
                    insertdata.InsertToEs(resultMsg)
                    logger.Debug("插入完Es所用时间:", time.Since(start))
                    esEnd := time.Since(start)
                    logger.Debug("插入完Es所用时间:", esEnd)
                    //事件推送
                    //go labelFilter.Judge(resultMsg)
                    labelFilter.PushSomthing(resultMsg)
                //}(msg)
            }
        }
@@ -118,7 +129,7 @@
func paramFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage {
    defer func() {
        if err := recover(); err != nil {
            logger.Info("解包过程的错误", err.(string))
            logger.Info("解包过程的异常捕获", err.(string))
        }
    }()
@@ -172,7 +183,7 @@
                for _, info := range yoloParam.Infos {
                    if info.Typ == 0 {
                        //logger.Debug("-------------yolo的坐标有几个",info.RcObj)
                        photoMap := structure.PhotoMap{Rects: rectFormat(info.RcObj), Score: float64(info.Prob) * 100, IsYolo: true}
                        photoMap := structure.PhotoMap{Rects: rectFormat(info.RcObj), Score: float64(info.Prob) * 100, IsYolo: true,Id:info.ObjID}
                        arg.Photo = append(arg.Photo, photoMap)
                        yoloNum++
                    }
ruleserver/attachInfo.go
New file
@@ -0,0 +1,42 @@
package ruleserver
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    uuid "github.com/satori/go.uuid"
    "ruleprocess/cache"
)
func GetAttachInfo(msg *protomsg.SdkMessage){
    //人脸检测,没有相似的底库人员
    push := new(protomsg.PushAttach)
    localConfig, err := cache.GetServerInfo()
    if err != nil {
        logger.Error("查询本机信息失败!")
    }
    logger.Info("localConfig信息:",localConfig)
    push.ServerId = localConfig.ServerId
    push.ServerName = localConfig.ServerName
    serverIp, err := GetLocalIP()
    push.LocalIp = serverIp
    // 查询cameraName
    camera, err := cache.GetCameraById(msg.Cid)
    if err != nil {
        logger.Error("查询摄像机信息失败")
    }
    push.Cam = &camera
    push.PushId = uuid.NewV4().String()
    // 视频地址占位符
    //localConfig1, err := cache.GetServerInfo()
    //if err != nil {
    //    panic("配置文件不合法")
    //}
    //logger.Info("请求视频路径:",msg.Push,serverIp,camera)
    // weedfsUrl := "http://" + localConfig1.WebPicIp + ":" + strconv.Itoa(int(localConfig1.WebPicPort)) + "/dir/assign"
    //if path,err := WeedFSClient.GetFid(weedfsUrl);err != nil {
    //    logger.Info("请求文件地址失败:",err)
    //} else {
    //    logger.Info("视频路径为:",path)
    //    push.VideoUrl = path
    //}
    msg.Push = push
}
ruleserver/geoPolygon.go
@@ -20,10 +20,30 @@
    return num1
}
//Point 坐标点
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//Rect 检测目标
type Rect struct {
    X      float64
    Y      float64
    Width  float64
    Height float64
}
//Pointfloat 坐标点
type Pointfloat struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//PintIsInPolygon 判断点是否在多边形内部
//point为要判断的坐标点
//polygon是多边形各点数组
func pintIsInPolygon(point structure.Pointfloat, polygon []structure.Point, widthScale float64, heightScale float64) bool {
func pintIsInPolygon(point Pointfloat, polygon []Point, widthScale float64, heightScale float64) bool {
    var nCross int = 0
    for i := 0; i < len(polygon); i++ {
@@ -56,14 +76,14 @@
func getLocation(rect structure.Rect, n int) ([]structure.Pointfloat, float64) {
    xArr := make([]float64, n) // 用切片不用数组,数组不能用变量定义长度
    yArr := make([]float64, n)
    pointArr := make([]structure.Pointfloat, 0, n*n)
    pointArr := make([]Pointfloat, 0, n*n)
    for i := 0; i < n; i++ {
        xArr[i] = rect.X + (rect.Width/float64(2*n))*float64(2*i+1)
        yArr[i] = rect.Y + (rect.Height/float64(2*n))*float64(2*i+1)
    }
    for i := 0; i < n; i++ {
        for j := 0; j < n; j++ {
            point := structure.Pointfloat{X: xArr[i], Y: yArr[j]}
            point := Pointfloat{X: xArr[i], Y: yArr[j]}
            pointArr = append(pointArr, point)
        }
    }
@@ -72,7 +92,7 @@
}
//ComputePolygonArea 计算任意多边形面积
func computePolygonArea(polygon []structure.Point) float64 {
func computePolygonArea(polygon []Point) float64 {
    pointNum := len(polygon)
    var s float64 = 0
    if pointNum < 3 {
@@ -86,7 +106,7 @@
}
//PgsInterPercent calculate percent of two polygon intersection  计算两个多边形的重叠占比
func PgsInterPercent(pgpts []structure.Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
func PgsInterPercent(pgpts []Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
    areapts, areaBox := getLocation(box, 10)
    var count = 0
ruleserver/geoPolygon_test.go
New file
@@ -0,0 +1,38 @@
package ruleserver
import (
    "basic.com/valib/logger.git"
    "encoding/json"
    "fmt"
    "ruleprocess/structure"
    "testing"
)
func TestPgsInterPercent(t *testing.T) {
    areaPoints := json2points("[{\"x\":582,\"y\":11},{\"x\":582,\"y\":525},{\"x\":943,\"y\":525},{\"x\":943,\"y\":11}]")
    widthScale := float64(2688) / 960
    heigthScale := float64(1520) / 540
    rec := structure.Rect{1333, 594,204,274}
    per := PgsInterPercent(areaPoints,rec,widthScale,heigthScale)
    fmt.Println(widthScale,heigthScale,per)
}
// 将字符串格式的坐标序列化为Point格式
func json2points(areaPoints string) []Point {
    var pts []Point
    if areaPoints == "[]" || areaPoints == "" {
        logger.Error("=====================此区域为全部区域")
        pts = append(pts, Point{0, 0})
        pts = append(pts, Point{0, 540})
        pts = append(pts, Point{960, 540})
        pts = append(pts, Point{960, 0})
    } else {
        err := json.Unmarshal([]byte(areaPoints), &pts)
        if err != nil {
            logger.Error("json.Unmarshal错误", err)
            panic("序列化坐标异常,程序退出")
        }
    }
    return pts
}
ruleserver/personTrack.go
@@ -3,11 +3,13 @@
import (
    "basic.com/pubsub/protomsg.git"
    "github.com/golang/protobuf/proto"
    "ruleprocess/logger"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
    "sync"
)
var TrackPond = make(map[string]*PersonTrack)
var lock = sync.RWMutex{}
type PersonTrack struct {
    Faces []*Face // 人脸的数组  改为数量
@@ -19,13 +21,10 @@
}
var num int = 25
// 检查是否前后两次的数据id是否完全相同(人脸)
func FaceIsSame(msg *protomsg.SdkMessage) {
    logger.Debug("+++++++++++++++++++++追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
    if msg.Tasklab == nil {
        logger.Info("数据为空,不必追踪")
        return
    }
    logger.Debug("+++++++++++++++++++++人脸追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
    for _, sdkinfo := range msg.Tasklab.Sdkinfos { // 遍历各算法的sdkData
        if sdkinfo.Sdktype == "FaceDetect" { // 人脸检测
            logger.Info("数据长度为:", len(sdkinfo.Sdkdata))
@@ -34,14 +33,18 @@
                FaceIsInPond(msg.Cid, sdkinfo)
            } else {
                if num > 0 { // 连续num次没有数据才算是没有数据,不然只算作丢帧
                    logger.Info("我认为你只是丢帧了,此时的num值为:",num)
                    logger.Info("我认为你只是丢帧了,此时的num值为:", num)
                    num--
                } else {
                    if TrackPond[msg.Cid] != nil {
                        logger.Info("如果不为空:", TrackPond[msg.Cid])
                        lock.Lock()
                        TrackPond[msg.Cid].Faces = nil
                        lock.Unlock()
                    } else {
                        lock.Lock()
                        TrackPond[msg.Cid] = &PersonTrack{Faces: nil}
                        lock.Unlock()
                        logger.Info("如果为空:", TrackPond[msg.Cid])
                    }
                    logger.Info("摄像机:" + msg.Cid + "-没有人脸,被重置为空")
@@ -54,63 +57,66 @@
}
//  追踪人体,检查数量是否一致
func BodyIsSame(msg *protomsg.SdkMessage) bool{
    logger.Debug("+++++++++++++++++++++追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
func BodyIsSame(args *structure.SdkDatas,msg *protomsg.SdkMessage) bool{
    logger.Debug("+++++++++++++++++++++人体追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
    for _, sdkinfo := range msg.Tasklab.Sdkinfos { // 遍历各算法的sdkData
        if sdkinfo.Sdktype == "Yolo" {
                    if len(sdkinfo.Sdkdata) > 1 {
                        yoloParam := protomsg.ParamYoloObj{}
                        err := proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam)
                        if err != nil {
                            logger.Info("解析yolo数据时出现错误", err)
                            continue
                        }
                        var yoloNum int = 0
                        for i := 0; i < len(yoloParam.Infos); i++ {
                            if yoloParam.Infos[i].Typ == 0 {
                                yoloNum++
                            }
                        }
                        if TrackPond[msg.Cid] != nil {
                            logger.Info("================追踪之前yolo的个数:", yoloNum, "现在缓存池中记录的个数:", TrackPond[msg.Cid].Yolo)
                        } else {
                            logger.Info("================追踪之前yolo的个数:", yoloNum, "还没有这个摄像机的缓存")
                        }
                        if yoloParam.Infos != nil && TrackPond[msg.Cid] != nil && yoloNum == TrackPond[msg.Cid].Yolo { // yolo的如果数量相同则视为不变、把yolo的sdkData清空
                            //yoloParam.Infos = (yoloParam.Infos)[0:0]
                            //sdkinfo.Sdkdata, err = proto.Marshal(&yoloParam)
                            //if err != nil {
                            //    logger.Error("yolo序列化错误", err)
                            //}
                            logger.Info("跟之前相同,清空yolo数据")
                            return true
                        } else {
                            if TrackPond[msg.Cid] != nil {
                                logger.Info("更新当前摄像机缓存池中的yolo个数:", yoloNum)
                                TrackPond[msg.Cid].Yolo = yoloNum
                            } else {
                                logger.Info("新建当前摄像机缓存池中的yolo个数:", yoloNum)
                                TrackPond[msg.Cid] = &PersonTrack{Yolo: yoloNum}
                            }
                            return false
                        }
            if len(sdkinfo.Sdkdata) > 1 {
                yoloParam := protomsg.ParamYoloObj{}
                err := proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam)
                if err != nil {
                    logger.Info("解析yolo数据时出现错误", err)
                    continue
                }
                var yoloNum int = 0
                for i := 0; i < len(yoloParam.Infos); i++ {
                    if yoloParam.Infos[i].Typ == 0 {
                        yoloNum++
                    }
                }
                if TrackPond[msg.Cid] != nil {
                    logger.Info("================追踪之前yolo的个数:", yoloNum, "现在缓存池中记录的个数:", TrackPond[msg.Cid].Yolo)
                } else {
                    logger.Info("================追踪之前yolo的个数:", yoloNum, "还没有这个摄像机的缓存")
                }
                if yoloParam.Infos != nil && TrackPond[msg.Cid] != nil && yoloNum == TrackPond[msg.Cid].Yolo { // yolo的如果数量相同则视为不变、把yolo的sdkData清空
                    yoloParam.Infos = (yoloParam.Infos)[0:0]
                    sdkinfo.Sdkdata, err = proto.Marshal(&yoloParam)
                    if err != nil {
                        logger.Error("yolo序列化错误", err)
                    }
                    delete(args.RuleResult,"yolo")
                    logger.Info("清除yolo标签,",args.RuleResult["yolo"])
                    logger.Info("跟之前相同,清空yolo数据,人体追踪结束")
                    return true
                } else {
                    if TrackPond[msg.Cid] != nil {
                        logger.Info("更新当前摄像机缓存池中的yolo个数:", yoloNum)
                        TrackPond[msg.Cid].Yolo = yoloNum
                    } else {
                        if TrackPond[msg.Cid] != nil {
                            TrackPond[msg.Cid].Yolo = 0
                        } else {
                            TrackPond[msg.Cid] = &PersonTrack{Yolo: 0}
                        }
                        logger.Info("摄像机:" + msg.Cid + "-没有yolo,被重置为0")
                        continue
                        logger.Info("新建当前摄像机缓存池中的yolo个数:", yoloNum)
                        TrackPond[msg.Cid] = &PersonTrack{Yolo: yoloNum}
                    }
                    return false
                }
            } else {
                if TrackPond[msg.Cid] != nil {
                    TrackPond[msg.Cid].Yolo = 0
                } else {
                    TrackPond[msg.Cid] = &PersonTrack{Yolo: 0}
                }
                logger.Info("摄像机:" + msg.Cid + "-没有yolo,被重置为0")
                continue
            }
        }
    }
    logger.Debug("---------------------------------追踪结束--------------------------------------")
    logger.Debug("---------------------------------人体追踪结束--------------------------------------")
    return false
}
func TrackOrNot(label map[string]interface{}) bool{
func TrackOrNot(label map[string]interface{}) bool {
    if label["yolo"] != nil && len(label["yolo"].([]structure.Result)) > 0 {
        for _,res := range label["yolo"].([]structure.Result) {
        for _, res := range label["yolo"].([]structure.Result) {
            if res.TimeLabel == "10" {
                return true
            }
@@ -120,11 +126,11 @@
}
// 过滤掉那些已在缓存中且分值更低的人脸,更新缓存(没有的加上,分值更新为更高的,多的删除)
func FaceIsInPond(cameraId string, sdkinfor *protomsg.SdkmsgWithTask) string {
func FaceIsInPond(cameraId string, sdkinfor *protomsg.SdkmsgWithTask) {
    if TrackPond[cameraId] != nil {
        logger.Info("----马前炮:", TrackPond[cameraId], "=====", len(TrackPond[cameraId].Faces))
        for _,face := range TrackPond[cameraId].Faces  {
            logger.Info("缓存中存储的face数据:",face.Id,face.Score)
        for _, face := range TrackPond[cameraId].Faces {
            logger.Info("缓存中存储的face数据:", face.Id, face.Score)
        }
        faceParam := protomsg.ParamFacePos{}
        err := proto.Unmarshal(sdkinfor.Sdkdata, &faceParam)
@@ -132,24 +138,29 @@
            logger.Info("解析face sdk数据时出现错误", err)
        }
        logger.Info("================追踪之前人脸的个数:", len(faceParam.Faces))
        for _,face := range faceParam.Faces  {
            logger.Info("新来的的face数据:",face.Pos.FaceID,face.Pos.FAngle.Confidence)
        for _, face := range faceParam.Faces {
            logger.Info("新来的的face数据:", face.Pos.FaceID, face.Pos.FAngle.Confidence)
        }
        var facesTemp = faceParam.Faces // 先把数据转存一份,不然一会儿数据删减之后找不到原始数据,不能让缓存数据更新了
        var facesTemp []protomsg.ResultFaceDetect
        for _, face := range faceParam.Faces {
            facesTemp = append(facesTemp, *face) // 先把数据转存一份,不然一会儿数据删减之后找不到原始数据,不能让缓存数据更新了
        }
        for i := 0; i < len(faceParam.Faces); {
            faceFlag := false
            for _, val := range TrackPond[cameraId].Faces {
                if faceParam.Faces[i].Pos.FaceID == val.Id && faceParam.Faces[i].Pos.FAngle.Confidence <= val.Score { // 在池子里并且分值更低,是要抛弃的数据
                    faceFlag = true
                    //return "true"
                    logger.Info("分值为:",faceParam.Faces[i].Pos.FAngle.Confidence,"--缓存的分值为:",val.Score,"此数据由于在池子中且分值更低,是要被抛弃的数据")
                    logger.Info("分值为:", faceParam.Faces[i].Pos.FAngle.Confidence, "--缓存的分值为:", val.Score, "此数据由于在池子中且分值更低,是要被抛弃的数据")
                    faceParam.Faces = append(faceParam.Faces[:i], faceParam.Faces[i+1:]...)
                    break
                }
                if faceParam.Faces[i].Pos.FaceID == val.Id && faceParam.Faces[i].Pos.FAngle.Confidence > val.Score { // 在池子里并且分值更高,更新缓存
                    faceFlag = true
                    logger.Info("分值由", val.Score, "更新为:", faceParam.Faces[i].Pos.FAngle.Confidence, "此数据由于在池子中且分值更高,是要被传递下去的数据")
                    lock.Lock()
                    val.Score = faceParam.Faces[i].Pos.FAngle.Confidence
                    lock.Unlock()
                }
            }
            if !faceFlag { // 此人脸不在池子中
@@ -158,18 +169,16 @@
                i++
            }
        }
        logger.Info("反序列化重新装配之前人脸的个数:",len(faceParam.Faces))
        sdkinfor.Sdkdata, err = proto.Marshal(&faceParam)
        if err != nil {
            logger.Error("face序列化错误", err)
        }
        //logger.Info("跟之前相同,清空人脸数据")
        // 反向循环 ,看那些缓存有而数据没有的就删除池子中的数据更新缓存
        logger.Info("反序列化重新装配之前人脸的个数:", len(faceParam.Faces))
        logger.Info("临时存储的新来数据:")
        for _, temp := range facesTemp {
            logger.Info("临时存储的新来的的face数据:",temp.Pos.FaceID,temp.Pos.FAngle.Confidence)
            logger.Info("临时存储的新来的的face数据:", temp.Pos.FaceID, temp.Pos.FAngle.Confidence)
        }
        sdkinfor.Sdkdata, err = proto.Marshal(&faceParam)
        if err != nil {
            logger.Error("人脸序列化错误", err)
        }
        // 反向循环 ,看那些缓存有而数据没有的就删除数据更新缓存
        for i := 0; i < len(TrackPond[cameraId].Faces); {
            flag := false
            for _, temp := range facesTemp {
@@ -182,11 +191,14 @@
            } else {
                // 此数据在缓存中但不在来的数据帧中,删除此数据更新缓存
                logger.Info("删除池子中的数据更新缓存")
                lock.Lock()
                TrackPond[cameraId].Faces = append(TrackPond[cameraId].Faces[:i], TrackPond[cameraId].Faces[i+1:]...)
                lock.Unlock()
            }
        }
    } else {
        return "false"
        lock.Lock()
        TrackPond[cameraId] = &PersonTrack{Faces: nil}
        lock.Unlock()
    }
    return "false"
}
ruleserver/readyDataForRule.go
@@ -3,19 +3,17 @@
import (
    "basic.com/dbapi.git"
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "encoding/json"
    "errors"
    "fmt"
    "github.com/go-yaml/yaml"
    "github.com/golang/protobuf/proto"
    "io/ioutil"
    "math"
    "nanomsg.org/go-mangos"
    "nanomsg.org/go-mangos/protocol/req"
    "nanomsg.org/go-mangos/transport/tcp"
    "net"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strconv"
    "time"
@@ -33,23 +31,6 @@
}
func Init() {
    data, err := ioutil.ReadFile("./config/conf.yml")
    if err != nil {
        fmt.Println("读取配置文件出错--", err)
        logger.Error("读取配置文件出错--", err)
    }
    c := conf{}
    //把yaml形式的字符串解析成struct类型
    yaml.Unmarshal(data, &c)
    logger.Debug("配置文件的值为:", c)
    serverIp = c.ServerIp
    serverPort = c.ServerPort
    dbTablePersons = c.DbTablePersons
    localConfig, err1 := cache.GetServerInfo()
    if err1 != nil {
        logger.Error("查询本机信息失败!")
    }
    logger.Debug("本机信息和server信息:", localConfig, serverIp, serverPort)
    go Push1()
}
@@ -80,7 +61,6 @@
            taskGroup = task
        }
    }
    logger.Debug("当前数据帧要匹配的规则组:-------------------------","摄像机id:",cameraId,"任务id",taskId)
    if taskGroup == nil  {
        return nil
    } else {
@@ -106,10 +86,10 @@
}
func Decimal(value float32) float64 {
    value1, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", float64(value)), 64)
    logger.Info("初步保留两位成str:",value1)
    //logger.Info("初步保留两位成str:",value1)
    n10 := math.Pow10(4)
    value2 := math.Trunc((value1+0.5/n10)*n10) / n10
    logger.Info("初步保留两位成str::::",value2)
    //logger.Info("初步保留两位成str::::",value2)
    return value2
}
// 取出某个时间规则的第几天的规则段集合
@@ -143,14 +123,14 @@
// 将字符串格式的坐标序列化为Point格式
func Json2points(areaPoints string) []structure.Point {
    var pts []structure.Point
func Json2points(areaPoints string) []Point {
    var pts []Point
    if areaPoints == "[]" || areaPoints == "" {
        logger.Error("=====================此区域为全部区域")
        pts = append(pts, structure.Point{0, 0})
        pts = append(pts, structure.Point{0, 540})
        pts = append(pts, structure.Point{960, 540})
        pts = append(pts, structure.Point{960, 0})
        pts = append(pts, Point{0, 0})
        pts = append(pts, Point{0, 540})
        pts = append(pts, Point{960, 540})
        pts = append(pts, Point{960, 0})
    } else {
        err := json.Unmarshal([]byte(areaPoints), &pts)
        if err != nil {
@@ -162,7 +142,7 @@
}
// 给目标填充liker
func FillLiker(arg *structure.Arg,tableId []string, compareThreshold float32) {
func fillLiker(tableId []string, compareThreshold float32,arg *structure.Arg) {
    //bytes := bigCache.GetComparePersonBaseInfo(tableId, arg.Feature, compareThreshold)
    comArg := &protomsg.CompareArgs{
        TableIds:tableId,
@@ -229,7 +209,7 @@
            if groupRule.Rules[j].SdkArgAlias == "compareBase" && groupRule.Rules[j].SdkArgValue == "" { // 配的参数是比对全部底库
                compareFlag = 1
            }
            if groupRule.Rules[j].SdkArgAlias == "threshold" {
            if groupRule.Rules[j].SdkArgAlias == "cmpThreshold" {
                v2, err := strconv.ParseFloat(groupRule.Rules[j].SdkArgValue, 32)
                if err != nil {
                    logger.Error("string转float32失败!")
@@ -256,19 +236,19 @@
                            //logger.Info("--------------看看compareFlag的值和tableId和areaMap.args的长度:",compareFlag,tableIds,len(areaMap.args))
                            for _, arg := range areaMap.Args {
                                arg.Liker = arg.Liker[0:0]
                                logger.Info("清空之后看看之前打的人脸标签变了没:")
                                if args.RuleResult["face"] != nil && len(args.RuleResult["face"].([]structure.FaceResult)) > 0 {
                                    for _, faceResult := range args.RuleResult["face"].([]structure.FaceResult) {
                                        for _,arg := range faceResult.Args {
                                            logger.Info("人员分值是:",arg.Score,"liker的数量为",arg.Liker)
                                        }
                                    }
                                }
                                //logger.Info("清空之后看看之前打的人脸标签变了没:")
                                //if args.RuleResult["face"] != nil && len(args.RuleResult["face"].([]FaceResult)) > 0 {
                                //    for _, faceResult := range args.RuleResult["face"].([]FaceResult) {
                                //        for _,arg := range faceResult.Args {
                                //            logger.Info("人员分值是:",arg.Score,"liker的数量为",arg.Liker)
                                //        }
                                //    }
                                //}
                                if compareFlag == 1 {
                                    FillLiker(arg,nil, threshold)
                                    fillLiker(nil, threshold, arg)
                                }
                                if compareFlag == 2 {
                                    FillLiker(arg,tableIds, threshold)
                                    fillLiker(tableIds, threshold, arg)
                                }
                                //logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
@@ -288,16 +268,17 @@
func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) {
    a.TargetNum = 0
    threshold := 0.5       // 相似度
    threshold := 80.0       // 相似度
    intersectionper := 0.2 // 占比
    size := 0.0            // 尺寸
    areaPoints := Json2points(a.AreaJson)
    widthScale := float64(arg.ImageWidth / 960)
    heigthScale := float64(arg.ImageHeight / 540)
    logger.Info("看看图片的width和height:",arg.ImageWidth,arg.ImageHeight)
    widthScale := float64(arg.ImageWidth) / 960
    heigthScale := float64(arg.ImageHeight) / 540
    for _, obj := range arg.Photo {
        //logger.Info("------------------看看sdkData:", arg.SdkName, "的Photo数据----------------", obj, "----顺便看看占比-----:", PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale))
        if threshold <= obj.Score && size <= float64(obj.Rects.Width*obj.Rects.Height) && intersectionper <= PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) {
        if  obj.Score >= threshold && float64(obj.Rects.Width*obj.Rects.Height) >= size && PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) >= intersectionper {
            // 这步要备齐表达式里所需要的所有参数
            a.TargetNum++
            arg1 := structure.Arg{obj.Id,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*structure.BaseInfo{}}
@@ -393,6 +374,7 @@
        // case <-ctx.Done():
        //     return
        case data := <- sender:
            logger.Info("比对进程入参:",data.TableIds,data.CompareThreshold)
            bytes,err1 := proto.Marshal(data)
            logger.Info("数据长度为:",len(bytes))
            if err1 != nil {
ruleserver/ruleToformula.go
@@ -1,21 +1,34 @@
package ruleserver
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/logger.git"
    "github.com/knetic/govaluate"
    "plugin"
    "ruleprocess/cache"
    "ruleprocess/structure"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "sort"
    "strconv"
    "strings"
    "sync"
    "time"
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
)
var rw sync.RWMutex // 读写锁
// 对单帧图像的判断 thisSdkDatas  当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil  (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas)
func Judge(args *structure.SdkDatas, message *protomsg.SdkMessage) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("规则模块儿的异常捕获:",err)
        }
    }()
    if len(args.Sdkdata) > 0 {
        // 拿到本摄像机的区域
        cameraPolygons := GetPolygons(args.CameraId)
@@ -60,32 +73,14 @@
                    }
                }
            }
            // 人体追踪
            // 如果标签中含有持续时间首次报警的timeLabel的话则不需要过人体追踪,不然就没的插入了
            fk := TrackOrNot(args.RuleResult)
            if !fk {
                BodyIsSame(args,message)
            }
        }
    }
}
func CallSo(sdkId string,rule *protomsg.Rule, am *structure.AreaMap) 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" {
        soName = "personUnsual.so"
    } else if sdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
        soName = "faceCompare.so"
    }
    p,err :=  plugin.Open("./algorithm/"+soName)
    if err != nil {
        panic(err)
    }
    f,err1 := p.Lookup("Entrance")
    if err1 != nil {
        panic("没有找到入口函数")
    }
    ruleResult := f.(func(rule *protomsg.Rule, am *structure.AreaMap)structure.LittleRuleResult)(rule,am)
    return ruleResult
}
func CallMiddleware(args *structure.SdkDatas,rule protomsg.GroupRule) ([]*structure.LittleRuleResult, string, string){
@@ -100,6 +95,7 @@
    a,b,c := f.(func(args *structure.SdkDatas,rule protomsg.GroupRule)([]*structure.LittleRuleResult, string, string))(args,rule)
    return a,b,c
}
func RunRule(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) (bool,[]int) {
    defer func() {
        if err := recover(); err != nil {
@@ -143,6 +139,7 @@
        if result.(bool) {
            // 最后过持续时间等时间维度的条件   把时间规则位置调整到这个位置是为了缓存数据
            cacheId := ""
            for j := 0; j < len(groupRule.Rules); j++ {
                for _, sdkData := range args.Sdkdata {
                    sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
@@ -153,14 +150,17 @@
                    if ipcId == sdkData.IpcId {
                        for _, areaMap := range sdkData.AreaMapList {
                            // 去开启一个定时器
                            duration(groupRule.Rules[j], groupRule.GroupId, areaMap, args, message)
                            cacheid := duration(groupRule.Rules[j], groupRule.GroupId, areaMap, args, message)
                            if cacheid != "" {
                                cacheId = cacheid
                            }
                        }
                    }
                }
            }
            // 进行定时器的处理和判断
            timeFlag := TimerAlarm(&label, groupRule.GroupId, result.(bool))
            if timeFlag == "01" || timeFlag == "10" || timeFlag == "11" { // 没有定时器或者满足定时器条件
            if timeFlag == "01" || timeFlag == "10" || timeFlag == "11" || cacheId != ""{ // 没有定时器或者满足定时器条件
                // 打人脸标签和yolo标签
                // 最后成功报警才把符合条件的人脸数据塞进结果标签里
                // 配了人脸的算法才把人脸的数据甩出来打标签
@@ -180,17 +180,19 @@
                        }
                    }
                }
                logger.Info("face标签的长度:",len(faces))
                //logger.Info("face标签的长度:",len(faces))
                //for _,face := range faces  {
                //    //logger.Debug("————————————————________________看看人脸的坐标:",face.Location)
                //}
                logger.Warn("___________________________________________________________________________终于走完万里长征")
                // 把他们的位置数据也传下去
                locations := []structure.Rect{}
                locations := []structure.TargetInfo{}
                for _, sdkData := range args.Sdkdata {
                    if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框
                        for _, areaMap := range sdkData.AreaMapList {
                            locations = append(locations, putYolosToResult(areaMap)...)
                            if areaMap.IsEffective {
                                locations = append(locations, putYolosToResult(areaMap)...)
                            }
                        }
                    }
                }
@@ -208,10 +210,32 @@
                    //logger.Info("-------------------yolo结果标签长度", len(args.RuleResult["yolo"].([]Result)))
                }
                if faceFlag {
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]structure.FaceResult), structure.FaceResult{structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []structure.Rect{}, polygonId, islink, label,}, faces})
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]structure.FaceResult), structure.FaceResult{structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []structure.TargetInfo{}, polygonId, islink,label,}, faces})
                    //logger.Info("-------------------face结果标签", len(args.RuleResult["face"].([]FaceResult)))
                    labelTypes = append(labelTypes,1)
                }
                // 给持续时间的第一张赋予缓存数据(遍历复制)
                if cacheId != "" { // 有这帧数据的缓存
                    tempMap := make(map[string]interface{})
                    for k, result := range args.RuleResult {
                        if k == "yolo" {
                            tempMap[k] = []structure.Result{}
                            for _, res := range result.([]structure.Result) {
                                tempMap[k] = append(tempMap[k].([]structure.Result), res)
                            }
                        }
                        if k == "face" {
                            tempMap[k] = []structure.FaceResult{}
                            for _, res := range result.([]structure.FaceResult) {
                                tempMap[k] = append(tempMap[k].([]structure.FaceResult), res)
                            }
                        }
                    }
                    rw.Lock()
                    TimeEleList[cacheId].CacheSdkData.RuleResult = tempMap
                    rw.Unlock()
                }
                return true,labelTypes
            } else {
                return false,[]int{}
@@ -247,11 +271,15 @@
    return faces
}
func putYolosToResult(am *structure.AreaMap) []structure.Rect {
    locations := []structure.Rect{}
func putYolosToResult(am *structure.AreaMap) []structure.TargetInfo {
    locations := []structure.TargetInfo{}
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            locations = append(locations, data.Location)
            location := structure.TargetInfo{}
            location.Rect = data.Location
            location.TargetId = data.Id
            location.TargetScore = data.Score
            locations = append(locations, location)
        }
    }
    //logger.Println("-----------------------------------------------听说你是空的?",faces)
@@ -264,21 +292,27 @@
    logger.Info("------------------------------------------当前是联动任务,规则是:", groupRule.GroupText)
    var flag bool = true
    var timeEle = TimeElement{N: 2, InitN: 2, GroupId: groupRule.GroupId}
    rw.Lock()
    for k, timeEle1 := range TimeEleList {
        if k == groupRule.GroupId {
            flag = false // 已经有了这个定时器就置为false 不再新增
            timeEle = *timeEle1
        }
    }
    //for _,ruleRe := range timeEle.RuleResults {
    //    logger.Info("联动数组里的数据----",ruleRe.CameraId,ruleRe.Sort)
    //}
    if flag { // 如果还没有这个定时器元素就新增一个
        //timeEle := TimeElement{N: 2, InitN: 2, GroupId: groupRule.GroupId} // 扔进去一个定时器元素
        //TimeEleList = make(map[string]timeElement)
        TimeEleList[groupRule.GroupId] = &timeEle // 定时器元素以规则组id为键
        logger.Info("---------------------------------------------联动任务创建了计数器并且计数器集合为:", TimeEleList)
        //logger.Info("---------------------------------------------联动任务创建了计数器并且计数器集合为:", TimeEleList)
        // 得出这组完整规则里涉及到几个摄像机,决定着数组里有几个结构体,去重添加方式
        for j := 0; j < len(groupRule.Rules); j++ {
            var flag1 bool = true
            //logger.Info("规则组信息:",groupRule.Rules[j].CameraId)
            for _, ruleRes := range TimeEleList[groupRule.GroupId].RuleResults {
                //logger.Info("联动数组里的数据:",ruleRes.CameraId,ruleRes.Sort)
                if groupRule.Rules[j].CameraId == ruleRes.CameraId {
                    flag1 = false
                }
@@ -288,6 +322,7 @@
            }
        }
    }
    rw.Unlock()
    // 往数组里赋值
    isOk,labelTypes := RunRule(args, groupRule, taskId, message, label)
    if isOk {
@@ -339,13 +374,14 @@
                result, _ := expression.Evaluate(nil) // 得到数学公式的结果
                if result.(bool) {
                    logger.Info("___________________________________________________________________联动任务报警")
                    if TimeEleList[groupRule.GroupId] != nil { // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                    rw.RLock()
                    if TimeEleList[groupRule.GroupId] != nil {  // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                        // 把数组里缓存的数据取出来一起报警
                        label.LinkCache = []structure.ResultMsg{}
                        for _, ruleRes := range TimeEleList[groupRule.GroupId].RuleResults {
                            label.LinkCache = append(label.LinkCache, ruleRes.CacheData)
                        }
                        logger.Debug("联动任务缓存了几个数据", len(label.LinkCache))
                        for i := 0; i < len(args.RuleResult["yolo"].([]structure.Result)); i++ {
                            if args.RuleResult["yolo"].([]structure.Result)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["yolo"].([]structure.Result)[i].Others.LinkCache = label.LinkCache
@@ -357,6 +393,7 @@
                            }
                        }
                    }
                    rw.RUnlock()
                }
            }
        } else {
@@ -385,95 +422,44 @@
        //        va.Result = strconv.FormatBool(isOk)
        //    }
        //}
        rw.Lock()
        for k, _ := range TimeEleList {
            if k == groupRule.GroupId {
                delete(TimeEleList, k)
                logger.Debug("因为定时器的一帧数据结果为false,干掉定时器")
            }
        }
        rw.Unlock()
        // 因为本帧数据不符合规则,所以也不用统计结果数组里的东西
    }
}
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *structure.AreaMap, args *structure.SdkDatas, message *protomsg.SdkMessage) {
func duration(rule *protomsg.Rule, groupId string, am *structure.AreaMap, args *structure.SdkDatas, message *protomsg.SdkMessage) string{
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
        if rule.SdkArgAlias == "duration" { //
            logger.Info("当前小规则是:---------", rule)
            //logger.Info("当前小规则是:---------", rule)
            // 先看看定时器元素队列中是否有这条规则的定时器,如果有就不能再次创建了
            rw.Lock()
            var flag bool = true
            for k, _ := range TimeEleList {
                if k == groupId+"+"+rule.Id {
                    flag = false // 有就置为false
                    logger.Info("有这个定时器,不再创建了:")
                    //logger.Info("有这个定时器,不再创建了:")
                }
            }
            if flag {
                timeLength, _ := strconv.Atoi(rule.SdkArgValue)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: structure.ResultMsg{message, args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: structure.ResultMsg{message, nil}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                //TimeEleList = make(map[string]timeElement)
                TimeEleList[groupId+"+"+rule.Id] = &timeEle // 定时器元素以当前持续时间小规则id为键
                logger.Info("创建了计数器")
                cacheId = groupId+"+"+rule.Id
            }
            rw.Unlock()
        }
    }
    return cacheId
}
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{}
}
ruleserver/server.go
@@ -4,7 +4,7 @@
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/gopherdiscovery.git"
    "github.com/gogo/protobuf/proto"
    "ruleprocess/logger"
    "basic.com/valib/logger.git"
    "time"
)
@@ -14,7 +14,7 @@
const (
    Discovery_Server = "tcp://0.0.0.0:40009"
    Discovery_UrlPubSub = "tcp://0.0.0.0:50009"
    Discovery_UrlPubSub = "tcp://0.0.0.0:50009"
)
//启动discovery的server
ruleserver/timeTicker.go
@@ -2,7 +2,7 @@
import (
    "fmt"
    "ruleprocess/logger"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
    "strings"
    "time"
@@ -34,33 +34,35 @@
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)
                    }
    //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)
                }
            case stop := <-stopChan:
                if stop {
                    logger.Info("定时器结束")
                    return
                    //os.Exit(0)
                if timeEle.GroupId != "" && timeEle.N == 0 {
                    // 说明是联动任务的时间窗口 到点儿了该销毁了,再来了再创建
                    delete(TimeEleList, k)
                }
            }
            rw.Unlock()
        case stop := <-stopChan:
            if stop {
                logger.Info("定时器结束")
                return
                //os.Exit(0)
            }
        }
    }(ticker)
    }
    //}(ticker)
}
func StopTimeTicker() {
    stopChan <- true
@@ -72,6 +74,7 @@
    var flagTime string //
    // 判断有无此规则组的定时器
    flag := false
    rw.Lock()
    for k, _ := range TimeEleList {
        //logger.Debug("-----------------看看这个key和groupId", k, groupId)
        if strings.Contains(k, groupId) && k != groupId{
@@ -133,6 +136,7 @@
            flagTime = "00"
        }
    }
    rw.Unlock()
    return flagTime
}
structure/rule.go
@@ -79,7 +79,7 @@
    DefenceState bool   // 是否布防
    AlarmLevel   int32  // 报警等级
    RuleText     string // 文字版规则组
    Location     []Rect // 目标的坐标
    Location     []TargetInfo // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink       bool   // 是否是联动任务
    Others
@@ -90,6 +90,12 @@
    TimeLabel string
}
type TargetInfo struct {
    Rect
    TargetId    uint64
    TargetScore float64
}
// 过规则库打上的标签
type FaceResult struct {
    Result
util/105.jpg
Binary files differ
util/simpleCV.go
@@ -9,7 +9,7 @@
    "image/color"
    "os"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "basic.com/valib/logger.git"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strings"
@@ -156,7 +156,11 @@
    }
}
func DrawPolygonOnImage(cameraId string, img protomsg.Image, results []structure.Result,url string) (maps map[string]interface{}, err0 error) {
<<<<<<< HEAD
=======
>>>>>>> a87978244bbb81f2fa7610560ed190acbaa422f8
func DrawPolygonOnImageForYolo(cameraId string, img protomsg.Image, results []structure.Result,url string) (maps map[string]interface{}, err0 error) {
    rook, _ := gocv.NewMatFromBytes(int(img.Height), int(img.Width), gocv.MatTypeCV8UC3, img.Data)
    //rook := gocv.IMRead("/home/user/workspace/ruleprocess/util/105.jpg",gocv.IMReadColor)
@@ -164,15 +168,20 @@
    yellow := color.RGBA{255, 255, 0, 0}
    red := color.RGBA{255, 0, 0, 0}
    scale := float64(img.Width) / 960 // 画图比例
    logger.Info("width:",img.Width,"--画图比例:",scale)
    // 分割区域id集合并根据id查询区域然后画框
    for _,result := range results  {
        polygonIds := strings.Split(result.AlarmPolygon,",")
        logger.Info("-----------------------看看报警区域id:",polygonIds)
        for i := 0; i < len(polygonIds)-1; i++ {
        for i := 0; i < len(polygonIds); i++ {
            polygon := getPolygonById(polygonIds[i],cameraId)
            if polygon.Polygon != "[]" {
            if polygon.Polygon != "[]" && polygon.Polygon != ""{
<<<<<<< HEAD
                DrawAPolygon(&rook,polygon.Polygon,yellow,scale)
=======
                logger.Debug("所画区域:",polygon.Polygon)
                DrawAPolygon(&rook,polygon.Polygon,yellow)
>>>>>>> a87978244bbb81f2fa7610560ed190acbaa422f8
            }
        }
    }
@@ -180,6 +189,42 @@
    for _,result := range results  {
        for _,rect := range result.Location {
            gocv.Rectangle(&rook, image.Rect(int(rect.X), int(rect.Y), int(rect.X+rect.Width), int(rect.Y+rect.Height)), red, 1)
        }
    }
    //return nil,nil
    maps,err0 = UploadFromMat(url,rook)
    return
}
func DrawPolygonOnImageForFace(cameraId string, img protomsg.Image, results []structure.FaceResult,url string) (maps map[string]interface{}, err0 error) {
    rook, _ := gocv.NewMatFromBytes(int(img.Height), int(img.Width), gocv.MatTypeCV8UC3, img.Data)
    //rook := gocv.IMRead("/home/user/workspace/ruleprocess/util/105.jpg",gocv.IMReadColor)
    defer rook.Close()
    yellow := color.RGBA{255, 255, 0, 0}
<<<<<<< HEAD
    scale := float64(img.Width) / 960 // 画图比例
    // 分割区域id集合并根据id查询区域然后画框
    for _,result := range results  {
        polygonIds := strings.Split(result.AlarmPolygon,",")
        for i := 0; i < len(polygonIds); i++ {
            polygon := getPolygonById(polygonIds[i],cameraId)
            if polygon.Polygon != "[]" && polygon.Polygon != ""{
                DrawAPolygon(&rook,polygon.Polygon,yellow,scale)
=======
    // 分割区域id集合并根据id查询区域然后画框
    for _,result := range results  {
        polygonIds := strings.Split(result.AlarmPolygon,",")
        logger.Info("-----------------------看看报警区域id:",polygonIds)
        for i := 0; i < len(polygonIds)-1; i++ {
            polygon := getPolygonById(polygonIds[i],cameraId)
            if polygon.Polygon != "[]" && polygon.Polygon != ""{
                logger.Debug("所画区域:",polygon.Polygon)
                DrawAPolygon(&rook,polygon.Polygon,yellow)
>>>>>>> a87978244bbb81f2fa7610560ed190acbaa422f8
            }
        }
    }
    //return nil,nil
@@ -215,20 +260,20 @@
    var cameraPolygons []protomsg.CameraPolygon
    cameraPolygons = cache.GetPolygonsByCameraId(cameraId)
    for _, polygon := range cameraPolygons {
        if polygon.Id == polygonId {
        if strings.Contains(polygonId,polygon.Id) {
            return polygon
        }
    }
    return protomsg.CameraPolygon{}
}
// 在图上画一个框
func DrawAPolygon(rook *gocv.Mat,polygonString string, color color.RGBA) {
func DrawAPolygon(rook *gocv.Mat,polygonString string, color color.RGBA,scale float64) {
    points := ruleserver.Json2points(polygonString)
    for index := 0; index < len(points); index++ {
        if index == len(points)-1 { // 闭合图形
            gocv.Line(rook, image.Pt(int(points[index].X*1.33), int(points[index].Y*1.33)), image.Pt(int(points[0].X*1.33), int(points[0].Y*1.33)), color, 2)
            gocv.Line(rook, image.Pt(int(points[index].X * scale), int(points[index].Y * scale)), image.Pt(int(points[0].X * scale), int(points[0].Y * scale)), color, 2)
        } else {
            gocv.Line(rook, image.Pt(int(points[index].X*1.33), int(points[index].Y*1.33)), image.Pt(int(points[index+1].X*1.33), int(points[index+1].Y*1.33)), color, 2)
            gocv.Line(rook, image.Pt(int(points[index].X * scale), int(points[index].Y * scale)), image.Pt(int(points[index+1].X * scale), int(points[index+1].Y * scale)), color, 2)
        }
    }
}
util/simpleCV_test.go
@@ -5,9 +5,9 @@
)
func TestDrawPolygonOnImage(t *testing.T)  {
    resp,err := DrawPolygonOnImage()
    if err != nil {
        t.Error("画框或者上传有问题")
    }
    t.Log("------=============",resp)
    //resp,err := DrawPolygonOnImage()
    //if err != nil {
    //    t.Error("画框或者上传有问题")
    //}
    //t.Log("------=============",resp)
}
util/upload.go
@@ -10,7 +10,7 @@
    "log"
    "mime/multipart"
    "net/http"
    "ruleprocess/logger"
    "basic.com/valib/logger.git"
    "time"
    "gocv.io/x/gocv"
)