更新cache解决区域重复问题,开始标签过滤器模块,把数据准备的代码拆出来
1个文件已删除
3个文件已添加
4个文件已修改
691 ■■■■ 已修改文件
go.mod 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/labelFilter.go 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/readyDataForLabel.go 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/ruleForLabel.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/timeTicker.go 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.mod
@@ -4,8 +4,9 @@
require (
    basic.com/dbapi.git v0.0.0-20190701055817-73bca225181f
    basic.com/pubsub/cache.git v0.0.0-20190711020946-ac4bfc72bf9c
    basic.com/pubsub/cache.git v0.0.0-20190712095028-e73efb4afc3b
    basic.com/pubsub/protomsg.git v0.0.0-20190709070734-b34c868adcc2
    basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00
    basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051
    basic.com/valib/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28
    basic.com/valib/gosdk.git v0.0.0-20190531034110-0062fdaaa05a // indirect
go.sum
@@ -6,10 +6,14 @@
basic.com/pubsub/cache.git v0.0.0-20190710092005-5d7ea0a4cbbc/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/cache.git v0.0.0-20190711020946-ac4bfc72bf9c h1:Gvhzx2JB97gHX9800NSzpUTNlcq5eJyo/EWAnzH6c6Y=
basic.com/pubsub/cache.git v0.0.0-20190711020946-ac4bfc72bf9c/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/cache.git v0.0.0-20190712095028-e73efb4afc3b h1:UAasACFqEYUBCuZkkdxYVc1QmSyB7McvNHS36QxDJp4=
basic.com/pubsub/cache.git v0.0.0-20190712095028-e73efb4afc3b/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/protomsg.git v0.0.0-20190708093242-02e81455712c h1:p6bCit0NDQvC9ziK9Zf815LXgTYWxjr4mn99gcdehyk=
basic.com/pubsub/protomsg.git v0.0.0-20190708093242-02e81455712c/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20190709070734-b34c868adcc2 h1:ygh9CQPS48KmXv+PNUrOcrMqIiDZOs11apnQdu9oGEY=
basic.com/pubsub/protomsg.git v0.0.0-20190709070734-b34c868adcc2/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/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28 h1:3hejanzPEBvZSSvjIqayB83/6/6SLLrX9oNZAdiYELg=
labelFilter/labelFilter.go
File was deleted
labelFilter/readyDataForLabel.go
New file
@@ -0,0 +1,30 @@
package labelFilter
import (
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
)
type Label struct {
    CameraId      string
    CameraName    string
    CameraAddr    string
    TaskId        string
    Persons       []ruleserver.Arg
    DefenceLevel  string
}
func (label *Label)DataFormatToLabel(result ruleserver.ResultMsg) Label {
    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.Persons = result.RuleResult["face"].([]ruleserver.Arg)
    //labelData.DefenceLevel = result.
    return Label{}
}
labelFilter/ruleForLabel.go
New file
@@ -0,0 +1 @@
package labelFilter
ruleserver/readyDataForRule.go
New file
@@ -0,0 +1,219 @@
package ruleserver
import (
    "basic.com/pubsub/cache.git/esutil"
    bigCache "basic.com/pubsub/cache.git"
    "basic.com/pubsub/protomsg.git"
    "basic.com/pubsub/sdkcompare.git"
    "encoding/json"
    "fmt"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "strconv"
    "strings"
    "time"
)
func init() {
    bigCache.Init()
}
// 以摄像机id查出跟其相关的所有任务下的所有规则组
func GetRuleGroup(cameraId string) []*protomsg.TaskGroupArgs {
    all := cache.GetCameraTaskRulesByCameraId(cameraId)
    return all
}
// 根据摄像机id拿到摄像机所有区域
func GetPolygons(cameraId string) []protomsg.CameraPolygon {
    var cameraPolygons []protomsg.CameraPolygon
    cameraPolygons = cache.GetPolygonsByCameraId(cameraId)
    logger.Debug("------=======查看下全部区域:",cameraPolygons)
    return cameraPolygons
}
// 保留四位小数
func Retain(f float32)(float32) {
    s:= strconv.FormatFloat(float64(f), 'f', 4, 64)
    v, err := strconv.ParseFloat(s, 32)
    if err != nil {
        logger.Error("保留四位小数转换错误")
    }
    return float32(v)
}
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []TimeRange {
    _, cameraTimeRule := cache.GetTimeRuleById(id)
    var timeRangeList []day
    err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)
    if err != nil {
        logger.Error("取时间规则时反序列化错误!")
    }
    for _, timerange := range timeRangeList {
        if timerange.Day == index {
            //logger.Println("取到的时间规则:", timerange.TimeRange)
            return timerange.TimeRange
        }
    }
    return nil
}
// 根据传入的字符串得到其在一周内的索引 周一到周日分别对应1到7
func getIndexOfWeek(weekday string) int {
    var weekdays = [7]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
    for k, value := range weekdays {
        if value == weekday {
            return k + 1 // 因为数据库中存的是1-7代表的周一到周日
        }
    }
    return 0
}
type TimeRange struct {
    Start string `json:"start"`
    End   string `json:"end"`
}
type day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
// 将字符串格式的坐标序列化为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
}
// 给目标填充liker
func (arg *Arg) fillLiker() {
    bytes := sdkcompare.GetComparePersonBaseInfo(nil, arg.Feature, 70)
    var m map[string]float32
    err1 := json.Unmarshal(bytes, &m)
    if err1 != nil {
        logger.Error("getBaseInfo解压错误", err1)
    }
    //logger.Info("----------------------------------------map是", m)
    ids := []string{}
    for key,_ := range m {
        ids = append(ids,key)
    }
    baseinfos, err1 := esutil.Dbpersoninfosbyid(ids)
    if err1 != nil {
        logger.Error("查询底库人员信息出错", err1)
    }
    fmt.Println("底库人员信息:",baseinfos)
    //baseinfo.CompareScore = Retain(val)
    //arg.Liker = append(arg.Liker, &baseinfo)
    //logger.Info("------------------第一次看args:",*arg)
}
// 人脸比对
func Compare(args *SdkDatas, groupRule *protomsg.GroupRule) {
    compareFlag := 0
    tableIds := ""
    // 看看是否有只配人脸比对算法但没有配对比库的规则,如果有,则比对对象为全部底库
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" { // 配了人脸比对
            if groupRule.Rules[j].SdkArgAlias == "compareBase" && groupRule.Rules[j].SdkArgValue != "" { // 配了比对底库的参数但没有配全部底库
                compareFlag = 2
                tableIds = groupRule.Rules[j].SdkArgValue + "," // 最后会多一个tableId,切出来的数组取len-1就可以
            }
            if groupRule.Rules[j].SdkArgAlias == "compareBase" && groupRule.Rules[j].SdkArgValue == "" { // 配的参数是比对全部底库
                compareFlag = 1
            }
        }
    }
    // 为了测试作下弊,直接让其比对全部底库
    //compareFlag = 1
    if compareFlag == 0 {
        logger.Info("没有配置对比底库参数")
        return
    }
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
            for _, sdkData := range args.Sdkdata {
                if sdkData.IpcId == "A8B73405-373D-4F23-CED2-A617EBD7EC55" { // 搜索到人脸检测的sdkdata 现在关于人脸的只有他一个sdk,全找他
                    logger.Info("============================================进行人脸对比")
                    for _, areaMap := range sdkData.AreaMapList {
                        logger.Info("-------------人脸比对之前目标数量",len(areaMap.args))
                        // 拿区域中每个人脸特征值去对比,填充其liker
                        if groupRule.Rules[j].PolygonId == areaMap.areaId {
                            logger.Info("--------------看看compareFlag的值:",compareFlag)
                            for _, arg := range areaMap.args {
                                if compareFlag == 1 {
                                    arg.fillLiker()
                                }
                                if compareFlag == 2 {
                                    array := strings.Split(tableIds, ",")
                                    logger.Info("--------------------------看看对比底库的值;",array)
                                    for i := 0; i < len(array)-1; i++ {
                                        arg.fillLiker()
                                    }
                                }
                                logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
                            areaMap.filterData = areaMap.args
                            //logger.Info("=======第一次看args:",(areaMap.filterData))
                        }
                        logger.Info("-------------------------------人脸对比之后的目标数量",len(areaMap.args))
                    }
                }
            }
        }
    }
}
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
func (a *AreaMap) CountAreaObjs(arg *SdkData) {
    a.targetNum = 0
    threshold := 0.0       // 相似度
    intersectionper := 0.2 // 占比
    size := 0.0            // 尺寸
    areaPoints := Json2points(a.areaJson)
    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) {
            // 这步要备齐表达式里所需要的所有参数
            a.targetNum++
            arg1 := Arg{obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*protomsg.Baseinfo{}}
            //logger.Println("放进去的arg:-------", arg1)
            a.args = append(a.args, &arg1)
            a.filterData = append(a.filterData, &arg1)
        }
    }
    a.time = time.Unix(time.Now().Unix(), 0).String()[11:16]
    a.keepRight = arg.KeepRight
    a.isStatic = arg.IsStatic
    //logger.Println("--------------------看看区域数据:",*a)
}
// 把sdk从数据帧上提取的按照区域分类归置
func SdkDataFormat(cameraId string, arg *SdkData, cameraPolygons []protomsg.CameraPolygon) {
    logger.Info("==================================本sdkData中解出来的目标数据=======================================")
    for _, photo := range arg.Photo {
        logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score)
    }
    for _, polygon := range cameraPolygons {
        //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon)
        areaMap := AreaMap{cameraId: cameraId, areaId: polygon.Id, areaJson: polygon.Polygon, triggerLine: polygon.TriggerLine, directionLine: polygon.DirectionLine}
        // 为每个摄像机区域填充数据
        areaMap.CountAreaObjs(arg)
        arg.AreaMapList = append(arg.AreaMapList, &areaMap)
    }
}
ruleserver/ruleToformula.go
@@ -1,7 +1,6 @@
package ruleserver
import (
    "encoding/json"
    "fmt"
    "ruleprocess/cache"
    "ruleprocess/logger"
@@ -10,56 +9,9 @@
    "strings"
    "time"
    bigCache "basic.com/pubsub/cache.git"
    "basic.com/pubsub/cache.git/esutil"
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
)
func init() {
    bigCache.Init()
}
// 任务
type Task struct {
    camID     string //摄像机ID
    taskID    string //任务ID
    sdkID     string //算法ID
    areaId    string //区域id
    areaName  string //区域名称
    topicType string //规则主题类型,目标/持续时间/灵敏度等
}
// 数据库中的规则元素
type SingleRule struct {
    Task
    operatorType     string // 操作符,>=,==...
    compareType      string // 对比类型,值,被选项
    compareValue     string // 对比的值
    ruleWithPrevious string // 跟上一条的逻辑关系
    groupId          string // 大规则id
}
// 数据库中单条子规则  跟数据库映射的
type CameraTaskArg struct {
    Id               string `json:"id"`
    CameraTaskId     string `json:"camera_task_id"`
    CameraId         string `json:"camera_id"`
    PolygonId        string `json:"polygon_id"`
    SdkId            string `json:"sdk_id"`
    SdkArgAlias      string `json:"sdk_arg_alias"`
    Operator         string `json:"operator"`      //操作符,>=,==...
    OperatorType     string `json:"operator_type"` //对比类型,值,被选项
    SdkArgValue      string `json:"sdk_arg_value"` //对比的值
    Sort             int    `json:"sort"`
    RuleWithPrevious string `json:"rule_with_previous"` //跟上一条的逻辑关系
    GroupId          string `json:"group_id"`           //大规则id
}
// sdk输出的图片提取参数数据之后的数据集合,也是传给下一步用于赋值的数据集合
type AreaMapList struct {
    areaMapList []AreaMap
}
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
@@ -71,11 +23,6 @@
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*protomsg.Baseinfo
}
type LikePerson struct {
    Id    string  // 与之相似的底库人员的id
    Score float64 // 与底库人员的相似值
}
// 每个区域内的图片数据集合
@@ -126,9 +73,6 @@
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []Arg, yolo: []Result, cacheData: SdkDatas, timeLabel: 0,1,2,3,4,5
}
// 将传递过来的参数转化为
//protomsg.SdkMessage.TaskLabel.SdkmsgWithTask.sdkdata
type ResultMsg struct {
    *protomsg.SdkMessage
    RuleResult map[string]interface{} // 过完规则后打的标签
@@ -148,42 +92,6 @@
    SdkName string // 记录下此结果是哪个sdk的结果
    Result  string // 已包含了前置连接符
    Sort    int32
}
//
type Face struct {
    Location Rect // 人脸坐标框
    SdkName  string
    ThftRes  protomsg.ThftResult
    Liker    []LikePerson // 相似人员(如果是单纯的人脸检测可无此项)
}
// 包含N条规则元素的一整条规则
type CompleteRule struct {
    rule string
}
// 根据摄像机id拿到摄像机所有区域
func GetPolygons(cameraId string) []protomsg.CameraPolygon {
    var cameraPolygons []protomsg.CameraPolygon
    cameraPolygons = cache.GetPolygonsByCameraId(cameraId)
    logger.Debug("------=======查看下全部区域:",cameraPolygons)
    return cameraPolygons
}
// 把sdk从数据帧上提取的按照区域分类归置
func SdkDataFormat(cameraId string, arg *SdkData, cameraPolygons []protomsg.CameraPolygon) {
    logger.Info("==================================本sdkData中解出来的目标数据=======================================")
    for _, photo := range arg.Photo {
        logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score)
    }
    for _, polygon := range cameraPolygons {
        //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon)
        areaMap := AreaMap{cameraId: cameraId, areaId: polygon.Id, areaJson: polygon.Polygon, triggerLine: polygon.TriggerLine, directionLine: polygon.DirectionLine}
        // 为每个摄像机区域填充数据
        areaMap.CountAreaObjs(arg)
        arg.AreaMapList = append(arg.AreaMapList, &areaMap)
    }
}
// 对单帧图像的判断 thisSdkDatas  当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil  (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas)
@@ -225,88 +133,6 @@
    }
}
// 给目标填充liker
func (arg *Arg) fillLiker() {
    bytes := bigCache.Getdbpersonmsg("", arg.Feature, true)
    var m map[string]float32
    err1 := json.Unmarshal(bytes, &m)
    if err1 != nil {
        logger.Error("getBaseInfo解压错误", err1)
    }
    //logger.Info("----------------------------------------map是", m)
    for key, val := range m {
        baseinfo, err1 := esutil.Dbpersoninfosbyid(key)
        if err1 != nil {
            logger.Error("查询底库人员信息出错", err1)
        }
        baseinfo.CompareScore = Retain(val)
        arg.Liker = append(arg.Liker, &baseinfo)
    }
    //logger.Info("------------------第一次看args:",*arg)
}
// 保留四位小数
func Retain(f float32)(float32) {
    s:= strconv.FormatFloat(float64(f), 'f', 4, 64)
    v, err := strconv.ParseFloat(s, 32)
    if err != nil {
        logger.Error("保留四位小数转换错误")
    }
    return float32(v)
}
func Compare(args *SdkDatas, groupRule *protomsg.GroupRule) {
    compareFlag := 0
    tableIds := ""
    // 看看是否有只配人脸比对算法但没有配对比库的规则,如果有,则比对对象为全部底库
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" { // 配了人脸比对
            if groupRule.Rules[j].SdkArgAlias == "compareBase" && groupRule.Rules[j].SdkArgValue != "" { // 配了比对底库的参数但没有配全部底库
                compareFlag = 2
                tableIds = groupRule.Rules[j].SdkArgValue + "," // 最后会多一个tableId,切出来的数组取len-1就可以
            }
            if groupRule.Rules[j].SdkArgAlias == "compareBase" && groupRule.Rules[j].SdkArgValue == "" { // 配的参数是比对全部底库
                compareFlag = 1
            }
        }
    }
    // 为了测试作下弊,直接让其比对全部底库
    //compareFlag = 1
    if compareFlag == 0 {
        logger.Info("没有配置对比底库参数")
        return
    }
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
            for _, sdkData := range args.Sdkdata {
                if sdkData.IpcId == "A8B73405-373D-4F23-CED2-A617EBD7EC55" { // 搜索到人脸检测的sdkdata 现在关于人脸的只有他一个sdk,全找他
                    logger.Info("============================================进行人脸对比")
                    for _, areaMap := range sdkData.AreaMapList {
                        logger.Info("-------------人脸比对之前目标数量",len(areaMap.args))
                        // 拿区域中每个人脸特征值去对比,填充其liker
                        if groupRule.Rules[j].PolygonId == areaMap.areaId {
                            logger.Info("--------------看看compareFlag的值:",compareFlag)
                            for _, arg := range areaMap.args {
                                if compareFlag == 1 {
                                    arg.fillLiker()
                                }
                                if compareFlag == 2 {
                                    array := strings.Split(tableIds, ",")
                                    logger.Info("--------------------------看看对比底库的值;",array)
                                    for i := 0; i < len(array)-1; i++ {
                                        arg.fillLiker()
                                    }
                                }
                                logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
                            areaMap.filterData = areaMap.args
                            //logger.Info("=======第一次看args:",(areaMap.filterData))
                        }
                        logger.Info("-------------------------------人脸对比之后的目标数量",len(areaMap.args))
                    }
                }
            }
        }
    }
}
func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string,message *protomsg.SdkMessage) bool {
    defer func() {
        if err := recover(); err != nil {
@@ -507,72 +333,7 @@
        return false
    }
}
// 判断是否符合定时器条件
func TimerAlarm(args *SdkDatas,groupId string,result bool) (string) {
    var flagTime string  //
    // 判断有无此规则组的定时器
    flag := false
    for k,_ := range TimeEleList {
        logger.Debug("-----------------看看这个key和groupId",k,groupId)
        if strings.Contains(k, groupId) {
            flag = true
        }
    }
    if flag {     // 有定时器
        if result { // 结果为真
            for k, timeEle := range TimeEleList {
                if strings.Contains(k, groupId) {
                    if timeEle.N == 0 && timeEle.AlarmFlag {
                        logger.Debug("-------------------------符合持续时间规则但并不是首次,不报警")
                        flagTime = "11"
                        args.RuleResult["timeLabel"] = flagTime
                    }
                    if timeEle.N == 0 && !timeEle.AlarmFlag { // 这组规则的定时器要全部等于0   暂且认为一组规则只有一个定时器
                        logger.Debug("———————————-------------首次符合持续时间规则并报警")
                        flagTime = "10"
                        timeEle.AlarmFlag = true
                        args.RuleResult["cacheData"] = timeEle.CacheSdkData
                        args.RuleResult["timeLabel"] = flagTime
                    }
                    if timeEle.N != 0 {
                        flagTime = "00"
                        // 有定时器但不为0把已打的标签删除
                        args.RuleResult = nil
                        logger.Debug("------------------------结果为真但计数器不到0,不报警,此时的计数器的值为:",timeEle.N)
                    }
                }
            }
        } else { // 结果为假
            for k, timeEle := range TimeEleList {
                if strings.Contains(k, groupId) {
                    if timeEle.AlarmFlag {
                        if timeEle.BufferFlag == 0 {
                            logger.Debug("------------------------------杀死定时器,报警此帧状态改变的数据,此时的计数器的值为",timeEle.N)
                            flagTime = "12"
                            args.RuleResult["timeLabel"] = flagTime
                            delete(TimeEleList,k)
                        } else {
                            if timeEle.BufferFlag > 0 {
                                timeEle.BufferFlag--
                            }
                        }
                    } else {
                        delete(TimeEleList,k)
                    }
                }
            }
        }
    } else { // 无定时器
        if result {
            flagTime = "01"
            args.RuleResult["timeLabel"] = flagTime
        } else {
            flagTime = "00"
        }
    }
    return flagTime
}
func putFaceToResult(am *AreaMap) []Arg {
    faces := []Arg{}
@@ -595,59 +356,6 @@
    }
    //logger.Println("-----------------------------------------------听说你是空的?",faces)
    return locations
}
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
func (a *AreaMap) CountAreaObjs(arg *SdkData) {
    a.targetNum = 0
    threshold := 0.0       // 相似度
    intersectionper := 0.2 // 占比
    size := 0.0            // 尺寸
    areaPoints := Json2points(a.areaJson)
    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) {
            // 这步要备齐表达式里所需要的所有参数
            a.targetNum++
            arg1 := Arg{obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*protomsg.Baseinfo{}}
            //logger.Println("放进去的arg:-------", arg1)
            a.args = append(a.args, &arg1)
            a.filterData = append(a.filterData, &arg1)
        }
    }
    a.time = time.Unix(time.Now().Unix(), 0).String()[11:16]
    a.keepRight = arg.KeepRight
    a.isStatic = arg.IsStatic
    //logger.Println("--------------------看看区域数据:",*a)
}
// 将字符串格式的坐标序列化为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
}
// 以摄像机id查出跟其相关的所有任务下的所有规则组
func GetRuleGroup(cameraId string) []*protomsg.TaskGroupArgs {
    all := cache.GetCameraTaskRulesByCameraId(cameraId)
    return all
}
// 联动任务的处理
@@ -993,39 +701,4 @@
    return LittleRuleResult{}
}
// 根据传入的字符串得到其在一周内的索引 周一到周日分别对应1到7
func getIndexOfWeek(weekday string) int {
    var weekdays = [7]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
    for k, value := range weekdays {
        if value == weekday {
            return k + 1 // 因为数据库中存的是1-7代表的周一到周日
        }
    }
    return 0
}
type TimeRange struct {
    Start string `json:"start"`
    End   string `json:"end"`
}
type day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []TimeRange {
    _, cameraTimeRule := cache.GetTimeRuleById(id)
    var timeRangeList []day
    err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)
    if err != nil {
        logger.Error("取时间规则时反序列化错误!")
    }
    for _, timerange := range timeRangeList {
        if timerange.Day == index {
            //logger.Println("取到的时间规则:", timerange.TimeRange)
            return timerange.TimeRange
        }
    }
    return nil
}
ruleserver/timeTicker.go
@@ -3,6 +3,7 @@
import (
    "fmt"
    "ruleprocess/logger"
    "strings"
    "time"
)
@@ -66,6 +67,73 @@
    TimeTicker()
}
// 判断是否符合定时器条件
func TimerAlarm(args *SdkDatas,groupId string,result bool) (string) {
    var flagTime string  //
    // 判断有无此规则组的定时器
    flag := false
    for k,_ := range TimeEleList {
        logger.Debug("-----------------看看这个key和groupId",k,groupId)
        if strings.Contains(k, groupId) {
            flag = true
        }
    }
    if flag {     // 有定时器
        if result { // 结果为真
            for k, timeEle := range TimeEleList {
                if strings.Contains(k, groupId) {
                    if timeEle.N == 0 && timeEle.AlarmFlag {
                        logger.Debug("-------------------------符合持续时间规则但并不是首次,不报警")
                        flagTime = "11"
                        args.RuleResult["timeLabel"] = flagTime
                    }
                    if timeEle.N == 0 && !timeEle.AlarmFlag { // 这组规则的定时器要全部等于0   暂且认为一组规则只有一个定时器
                        logger.Debug("———————————-------------首次符合持续时间规则并报警")
                        flagTime = "10"
                        timeEle.AlarmFlag = true
                        args.RuleResult["cacheData"] = timeEle.CacheSdkData
                        args.RuleResult["timeLabel"] = flagTime
                    }
                    if timeEle.N != 0 {
                        flagTime = "00"
                        // 有定时器但不为0把已打的标签删除
                        args.RuleResult = nil
                        logger.Debug("------------------------结果为真但计数器不到0,不报警,此时的计数器的值为:",timeEle.N)
                    }
                }
            }
        } else { // 结果为假
            for k, timeEle := range TimeEleList {
                if strings.Contains(k, groupId) {
                    if timeEle.AlarmFlag {
                        if timeEle.BufferFlag == 0 {
                            logger.Debug("------------------------------杀死定时器,报警此帧状态改变的数据,此时的计数器的值为",timeEle.N)
                            flagTime = "12"
                            args.RuleResult["timeLabel"] = flagTime
                            delete(TimeEleList,k)
                        } else {
                            if timeEle.BufferFlag > 0 {
                                timeEle.BufferFlag--
                            }
                        }
                    } else {
                        delete(TimeEleList,k)
                    }
                }
            }
        }
    } else { // 无定时器
        if result {
            flagTime = "01"
            args.RuleResult["timeLabel"] = flagTime
        } else {
            flagTime = "00"
        }
    }
    return flagTime
}
// 结构体根据某字段排序
type SubList []*RuleResult