panlei
2019-12-09 42e6fe67c0c8cb51bf8ac13460f562672fd20c3e
es做成so
2 文件已重命名
2个文件已修改
919 ■■■■■ 已修改文件
algorithm/insertEs/EsClient.go 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/insertEs/config.go 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/insertEs/insertDataToEs.go 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/insertDataToEs.go 903 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/insertEs/EsClient.go
algorithm/insertEs/config.go
algorithm/insertEs/insertDataToEs.go
@@ -104,20 +104,7 @@
    rules []structure.Result
}
func InsertToEs(msg structure.ResultMsg) {
    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.AIOcean.IndexName + "/" + EsInfo.EsIndex.AIOcean.IndexType+"?refresh=true"
    serverIp = localConfig1.AlarmIp
    serverPort = strconv.Itoa(int(localConfig1.AlarmPort))
func InsertToEs(msg structure.ResultMsg){
    for k,results := range msg.RuleResult {
        if results != nil && len(results.([]structure.Result)) > 0{
            switch k {
@@ -135,7 +122,6 @@
        }
    }
}
// 往es中插入人脸类型数据
func InsertFace(msg structure.ResultMsg,key string, results interface{}) {
        logger.Info("往es插入抓拍数据")
insertdata/insertDataToEs.go
@@ -1,910 +1,19 @@
package insertdata
import (
    "encoding/base64"
    "encoding/json"
    "errors"
    "net"
    "strconv"
    "time"
    "github.com/golang/protobuf/proto"
    "github.com/satori/go.uuid"
    "basic.com/valib/logger.git"
    "ruleprocess/cache"
    "plugin"
    "ruleprocess/structure"
    "basic.com/pubsub/protomsg.git"
    "basic.com/pubsub/esutil.git"
    "ruleprocess/ruleserver"
    "ruleprocess/util"
)
var weedfsUrl, videoPersonUrl, personAction string
var serverIp string
var serverPort string
type conf struct {
    PhotoUrl       string `yaml:"photoUrl"`
    VideoPersons   string `yaml:"videoPersons"`
    PersonAction   string `yaml:"personAction"`
    ServerIp       string `yaml:"serverIp"`
    ServerPort     string `yaml:"serverPort"`
    DbTablePersons string `yaml:"dbTablePersons"`
}
type LinkInfo struct {
    Id              string                `json:"id"`
    CameraId        string                `json:"cameraId"`
    CameraAddr      string                `json:"cameraAddr"`
    CameraName      string                `json:"cameraName"`
    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"`
    ShowLabels      string                `json:"showLabels"`
    OtherLabels     string                `json:"otherLabels"`
    VideoUrl        string                `json:"videoUrl"`
    AnalyServerId   string                `json:"analyServerId"`
    AnalyServerName string                `json:"analyServerName"`
    AnalyServerIp   string                `json:"analyServerIp"`
    ClusterId       string                `json:"clusterId"`
    IsAlarm         bool                  `json:"isAlarm"`
    IsAckAlarm      bool                  `json:"isAckAlarm"`
    IsCollect       bool                  `json:"isCollect"`
    IsDelete        bool                  `json:"isDelete"`
    BaseInfo        []*structure.BaseInfo `json:"baseInfo"`
    TargetInfo      []Target              `json:"targetInfo"`
}
//  统一的数据结构
type PerVideoPicture struct {
    LinkInfo
    LinkTag            string                `json:"linkTag"`
    LinkTagInfo     []*LinkInfo           `json:"linkTagInfo"`
}
type SourceTarget struct {
    TargetId       string  `json:"targetId"`
    TargetScore    float64 `json:"targetScore"`
    TargetType     string  `json:"targetType"`
    Feature        string  `json:"feature"`
    PicSmUrl       string  `json:"picSmUrl"`
    TargetLocation Points  `json:"targetLocation"`
}
type Target struct {
    SourceTarget
    AttachTarget SourceTarget `json:"attachTarget"`
}
type Points struct {
    TopLeft     Point `json:"topLeft"`
    BottomRight Point `json:"bottomRight"`
}
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
type AlarmRule struct {
    GroupId      string `json:"groupId"`
    AlarmLevel   string `json:"alarmLevel"`
    RuleText     string `json:"ruleText"`
    DefenceState bool   `json:"defenceState"`
    LinkInfo     string `json:"linkInfo"`
}
// 一个obj对多个规则组的归置人脸的结构体 可用于人脸 可用于车牌
type ObjAndRules struct {
    structure.Arg
    rules []structure.Result
}
func InsertToEs(msg structure.ResultMsg) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("es模块儿的异常捕获:", err)
        }
    }()
    localConfig1, err := cache.GetServerInfo()
    p,err :=  plugin.Open("./algorithm/insertEs.so")
    if err != nil {
        panic("配置文件不合法")
        panic(err)
    }
    weedfsUrl = "http://" + localConfig1.WebPicIp + ":" + strconv.Itoa(int(localConfig1.WebPicPort)) + "/submit"
    videoPersonUrl = "http://" + localConfig1.AlarmIp + ":" + strconv.Itoa(int(localConfig1.AlarmPort)) + "/" + EsInfo.EsIndex.AIOcean.IndexName + "/" + EsInfo.EsIndex.AIOcean.IndexType+"?refresh=true"
    serverIp = localConfig1.AlarmIp
    serverPort = strconv.Itoa(int(localConfig1.AlarmPort))
    for k,results := range msg.RuleResult {
        if results != nil && len(results.([]structure.Result)) > 0{
            switch k {
            case "yolo":
                InsertYolo(msg,k,results)
            case "face":
                InsertFace(msg,k,results)
            case "plate":
                InsertFace(msg,k,results)
            case "track":
                InsertFace(msg,k,results)
            case "target":
                InsertLastTarget(msg)
            }
        }
    }
}
// 往es中插入人脸类型数据
func InsertFace(msg structure.ResultMsg,key string, results interface{}) {
        logger.Info("往es插入抓拍数据")
        faces := []*ObjAndRules{}
        faces = PutFace(faces, results.([]structure.Result))
        //logger.Info("整理后的数据:",faces)
        if faces != nil {
            logger.Warn("face不为nil")
            var imgMaxUrl []string = []string{}
            var picTime string = ""
            for _, face := range faces {
                // 上传大图
                // 解压缩并上传图片
                bdata, err := util.UnCompress(msg.Data)
                if err != nil {
                    panic("解压缩图片时出现错误")
                }
                alarmRules := []AlarmRule{}
                //logger.Info("循环每一个目标")
                for _, faceResult := range face.rules {
                    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)
                // 先传小图,再传大图,防止脸上有线
                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),face.Type)
                resp, err := util.PostFormBufferData1(weedfsUrl, bytes, uuid.NewV4().String())
                if err != nil {
                    logger.Error("上传小图出错")
                }
                // 上传大图
                if len(imgMaxUrl) == 0 {
                    bigPhotoUrl := make(map[string]interface{})
                    bigPhotoUrl, err = util.DrawPolygonOnImageForFace(msg.Cid, i, msg.RuleResult["face"].([]structure.Result), weedfsUrl)
                    logger.Debug("========大图路径:", bigPhotoUrl)
                    imgMaxUrl = append(imgMaxUrl, bigPhotoUrl["fileUrl"].(string))
                    picTime = i.Timestamp
                }
                lable, lableAttach := Feature2Jsonstr(*face)
                var target = new(Target)
                target.TargetId = face.Id
                target.TargetScore = face.Score
                target.TargetType = face.Type
                target.Feature = base64.StdEncoding.EncodeToString(face.Feature)
                target.PicSmUrl = resp["fileUrl"].(string)
                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}}
                target.AttachTarget = SourceTarget{face.AttachArg.Id,face.AttachArg.Score,face.AttachArg.Type,base64.StdEncoding.EncodeToString(face.AttachArg.Feature),"",Points{TopLeft: Point{face.AttachArg.Location.X, face.AttachArg.Location.Y}, BottomRight: Point{face.AttachArg.Location.X + face.AttachArg.Location.Width, face.AttachArg.Location.Y + face.AttachArg.Location.Height}}}
                var targetInfos []Target
                targetInfos = append(targetInfos, *target)
                sdkname := ""
                id := face.Uuid
                switch key {
                case "face":
                    sdkname = "人脸"
                case "plate":
                    sdkname = "车牌识别"
                case "track":
                    sdkname = "人员跟踪"
                    if len(face.Liker) == 1{
                        id = face.Liker[0].TargetId
                    }
                }
                //logger.Info("人脸目标target:",targetInfos)
                pervideo := PerVideoPicture{LinkInfo{
                    id,
                    msg.Cid,
                    msg.Push.Cam.Addr,
                    msg.Push.Cam.Name,
                    picTime,
                    imgMaxUrl,
                    msg.Tasklab.Taskid,
                    msg.Tasklab.Taskname,
                    sdkname,
                    "",
                    alarmRules,
                    time.Now().Format("2006-01-02 15:04:05"), // 只检测,没有比对时间
                    lable,
                    lableAttach,
                    "",
                    msg.Push.ServerId,
                    msg.Push.ServerName,
                    msg.Push.LocalIp,
                    "",
                    true,
                    false,
                    false,
                    false,
                    face.Liker,
                    targetInfos,
                },
                    "",
                    []*LinkInfo{},
                }
                requstbody, err := json.Marshal(pervideo)
                if err != nil {
                    logger.Info("json parse error ", err)
                    return
                }
                if key == "track" && len(face.Liker) == 1{
                    esid := face.Liker[0].TargetId
                    returnMsg, err1 := esutil.AppendTargetInfo(esid, string(requstbody),EsInfo.EsIndex.AIOcean.IndexName,serverIp,serverPort)
                    if err1 != nil {
                        logger.Error("追加数据出错!---", err1)
                    } else {
                        logger.Info("插入es返回的信息:", returnMsg)
                        // 发出录像信号
                        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: face.Uuid, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{"-1"}, Type: 1})
                    }
                } else {
                    resp1, err1 := EsReq("POST", videoPersonUrl, requstbody)
                    if err1 != nil {
                        logger.Error("上传ES出错!---", err1)
                    } else {
                        logger.Info("插入es返回的信息:", resp1)
                        // 发出录像信号
                        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: face.Uuid, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{"-1"}, Type: 1})
                    }
                }
            }
        }
}
// 归置人脸
func PutFace(objs []*ObjAndRules, resutls []structure.Result) []*ObjAndRules {
    for _, faceResult := range resutls {
        objs = hebingFace(objs, faceResult)
    }
    return objs
}
func hebingFace(objs []*ObjAndRules, faceResult structure.Result) []*ObjAndRules {
    for _, arg := range faceResult.AlarmObj {
        // 拿到每一张人脸
        //logger.Info("归置人脸时相似者的数量:", len(arg.Liker))
        flag := false
        for _, face := range objs {
            //for _, lik := range face.Liker {
            //    //logger.Warn("--------合并人脸时相似者:", lik.PersonId, lik.TableName)
            //}
            if arg.Id == face.Id {
                flag = true
                face.rules = append(face.rules, faceResult)
                // 相似者去重归并
                for _, liker := range arg.Liker {
                    flag1 := true
                    for _, liker1 := range face.Liker {
                        if liker.TargetId == liker1.TargetId {
                            flag1 = false
                        }
                    }
                    if flag1 {
                        face.Liker = append(face.Liker, liker)
                    }
                }
                //face.Liker = append(face.Liker,arg.Liker...)
            }
        }
        if !flag {
            objs = append(objs, &ObjAndRules{*arg, []structure.Result{faceResult}})
        }
    }
    return objs
}
// 往es中插入yolo数据
func InsertYolo(msg structure.ResultMsg,key string, results interface{}) {
        // 先判断一下数据带的规则标签是否有可以插入的
        flag := false
        for _, res := range msg.RuleResult["yolo"].([]structure.Result) {
            //logger.Info("定时器打的数字标签:",res.Others.TimeLabel)
            if res.Others.TimeLabel == "01" || res.Others.TimeLabel == "10" {
                flag = true
            }
        }
        if flag {
            logger.Info("往ES插yolo数据")
            var sdkNames string = ""
            alarmRules := []AlarmRule{}
            var targetInfos []Target
            url := []string{}
            for _, yoloResult := range results.([]structure.Result) {
                if yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10" {
                    // 拼出sdkname
                    //logger.Info("应该进来才对的")
                    sdkNames = sdkNames + yoloResult.SdkName
                    alarm := ChangeToString(yoloResult.DefenceState, yoloResult.AlarmLevel)
                    linkInfo := ""
                    if yoloResult.IsLink {
                        linkInfo = "联动任务"
                    }
                    alarmRules = append(alarmRules, AlarmRule{yoloResult.RuleGroupId, alarm, yoloResult.RuleText, yoloResult.DefenceState, linkInfo})
                    //logger.Info("打印任务名称:", )
                    // 上传缓存数据的图片拿到url
                    if yoloResult.Others.CacheData != nil {
                        //InsertYolo(msg.RuleResult["cacheData"].(ruleserver.ResultMsg))
                        // 把缓存的数据上传后得到地址存进去
                        // 解压缩并上传图片
                        msgs := yoloResult.Others.CacheData
                        for _, msg1 := range msgs {
                            bdata, err := util.UnCompress(msg1.Data)
                            if err != nil {
                                panic("解压缩图片时出现错误")
                            }
                            i := protomsg.Image{}
                            err = proto.Unmarshal(bdata, &i)
                            resp1, err1 := util.DrawPolygonOnImageForYolo(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            if err1 != nil {
                                logger.Error("缓存数据画框或上传图片服务器出错", err)
                            } else {
                                logger.Info("上传的图片信息:", resp1)
                            }
                            if resp1["fileUrl"] != nil {
                                url = append(url, resp1["fileUrl"].(string))
                            }
                        }
                    }
                    // 装配目标信息数据
                    for _, target := range yoloResult.AlarmObj {
                        // 去重添加
                        var flag = true
                        for _, selectTarget := range targetInfos {
                            if target.Id == selectTarget.TargetId {
                                flag = false
                                break
                            }
                        }
                        if flag {
                            var target1 = new(Target)
                            target1.TargetId = target.Id
                            target1.TargetScore = target.Score
                            target1.TargetType = "action"
                            target1.TargetLocation = Points{TopLeft: Point{target.Location.X, target.Location.Y}, BottomRight: Point{target.Location.X + target.Location.Width, target.Location.Y + target.Location.Height}}
                            targetInfos = append(targetInfos, *target1)
                        }
                    }
                }
            }
            // 联动图像的处理
            linkTagInfos := []*LinkInfo{}
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if (yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10") && yoloResult.Others.LinkCache != nil && len(yoloResult.Others.LinkCache) > 1 {
                    for _, msg2 := range yoloResult.Others.LinkCache {
                        // 把msg2的数据装配成一个PerVideoPicture结构体
                        if msg2.Cid != msg.Cid {
                            linkTagInfos = append(linkTagInfos, msg2PersonVideo(msg2))
                        }
                    }
                }
            }
            linkTag := ""
            if len(linkTagInfos) > 0 {
                linkTag = "联动任务"
            }
            isAlarm := false
            resp := make(map[string]interface{})
            // 解压缩并上传图片
            bdata, err := util.UnCompress(msg.Data)
            if err != nil {
                panic("解压缩图片时出现错误")
            }
            i := protomsg.Image{}
            err = proto.Unmarshal(bdata, &i)
            if len(alarmRules) > 0 {
                isAlarm = true
                //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                resp, err = util.DrawPolygonOnImageForYolo(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                if err != nil {
                    logger.Error("画框或上传图片服务器出错", err)
                    return
                } else {
                    logger.Info("上传的图片信息:", resp)
                }
            } else {
                isAlarm = false
                // 不是报警数据不存
                return
            }
            if resp["fileUrl"] != nil {
                url = append(url, resp["fileUrl"].(string))
                //esDataId := uuid.NewV4().String()
                peraction := PerVideoPicture{LinkInfo{
                    msg.Push.PushId,
                    msg.Cid,
                    msg.Push.Cam.Addr,
                    msg.Push.Cam.Name,
                    time.Now().Format("2006-01-02 15:04:05"),
                    url,
                    msg.Tasklab.Taskid,
                    msg.Tasklab.Taskname,
                    sdkNames,
                    time.Now().Format("2006-01-02 15:04:05"),
                    alarmRules,
                    i.Timestamp,
                    "",
                    "",
                    "",
                    msg.Push.ServerId,
                    msg.Push.ServerName,
                    msg.Push.LocalIp,
                    "",
                    isAlarm,
                    false,
                    false,
                    false,
                    nil,
                    targetInfos,
                },
                    linkTag,
                    linkTagInfos,
                }
                requstbody, err := json.Marshal(peraction)
                if len(linkTagInfos) > 0 {
                    logger.Info("联动任务1111")
                }
                if err != nil {
                    logger.Info("json parse error ", err)
                    return
                }
                resp1, err2 := EsReq("POST", videoPersonUrl, requstbody)
                if err2 != nil {
                    logger.Error("往ES插入数据失败", err)
                } else {
                    logger.Debug("插入es返回的数据信息是(yolo):", resp1)
                    // 发出录像信号
                    ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{"-1"}, Type: 2})
                    for index, link := range linkTagInfos {
                        logger.Info("联动任务的录像信号:", index)
                        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: link.CameraId, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{strconv.Itoa(index)}, Type: 2})
                    }
                    logger.Warn("__________________________________________往ES插入yolo数据成功")
                    //os.Exit(1)
                }
            }
        }
}
// 插入目标持续时间数据
func InsertLastTarget(msg structure.ResultMsg) {
    if msg.RuleResult["target"] != nil && len(msg.RuleResult["target"].([]structure.Result)) > 0 {
        // 先判断一下数据带的规则标签是否有可以插入的
        logger.Info("插入定时目标信息:", len(msg.RuleResult["target"].([]structure.Result)))
        for _, yoloResult := range msg.RuleResult["target"].([]structure.Result) {
            // 装载目标信息`
            // 如果有首次报警的则本帧数据可以插入
            insertFlag := false
            alarmNum := 0
            for _, obj := range yoloResult.AlarmObj {
                if obj.TimeLable == "10" {
                    insertFlag = true
                    alarmNum++
                }
            }
            if insertFlag {
                logger.Info("报警目标个数:", alarmNum)
                // 获取目标缓存图片
                url := []string{}
                //InsertYolo(msg.RuleResult["cacheData"].(ruleserver.ResultMsg))
                // 把缓存的数据上传后得到地址存进去
                // 解压缩并上传图片
                url1 := uploadImg(yoloResult.AlarmObj[0].CacheData)
                url = append(url, url1)
                // 添加报警规则组
                sdkNames := ""
                alarmRules := []AlarmRule{}
                sdkNames = sdkNames + yoloResult.SdkName
                alarm := ChangeToString(yoloResult.DefenceState, yoloResult.AlarmLevel)
                linkInfo := ""
                if yoloResult.IsLink {
                    linkInfo = "联动任务"
                }
                alarmRules = append(alarmRules, AlarmRule{yoloResult.RuleGroupId, alarm, yoloResult.RuleText, yoloResult.DefenceState, linkInfo})
                // 联动图像的处理
                linkTagInfos := []*LinkInfo{}
                for _, yoloResult := range msg.RuleResult["target"].([]structure.Result) {
                    if (yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10") && yoloResult.Others.LinkCache != nil && len(yoloResult.Others.LinkCache) > 1 {
                        for _, msg2 := range yoloResult.Others.LinkCache {
                            // 把msg2的数据装配成一个PerVideoPicture结构体
                            if msg2.Cid != msg.Cid {
                                linkTagInfos = append(linkTagInfos, msg2PersonVideo(msg2))
                            }
                        }
                    }
                }
                linkTag := ""
                if len(linkTagInfos) > 0 {
                    linkTag = "联动任务"
                }
                isAlarm := false
                resp := make(map[string]interface{})
                // 解压缩并上传本帧数据图片
                bdata1, err := util.UnCompress(msg.Data)
                if err != nil {
                    panic("解压缩图片时出现错误")
                }
                i := protomsg.Image{}
                err = proto.Unmarshal(bdata1, &i)
                if len(alarmRules) > 0 {
                    isAlarm = true
                    //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                    resp, err = util.DrawPolygonOnImageForYolo(msg.Cid, i, msg.RuleResult["target"].([]structure.Result), weedfsUrl)
                    if err != nil {
                        logger.Error("画框或上传图片服务器出错", err)
                        return
                    } else {
                        logger.Info("上传的图片信息:", resp)
                    }
                } else {
                    isAlarm = false
                    // 不是报警数据不存
                    return
                }
                // 整合目标
                var targetInfos []Target
                for _, target := range yoloResult.AlarmObj {
                    // 去重添加
                    var flag = true
                    for _, selectTarget := range targetInfos {
                        if target.Id == selectTarget.TargetId {
                            flag = false
                            break
                        }
                    }
                    if flag {
                        var target1 = new(Target)
                        target1.TargetId = target.Id
                        target1.TargetScore = target.Score
                        target1.TargetType = "action"
                        target1.TargetLocation = Points{TopLeft: Point{target.Location.X, target.Location.Y}, BottomRight: Point{target.Location.X + target.Location.Width, target.Location.Y + target.Location.Height}}
                        targetInfos = append(targetInfos, *target1)
                    }
                }
                if resp["fileUrl"] != nil {
                    url = append(url, resp["fileUrl"].(string))
                    if len(url) == 1 {
                        return
                    }
                    //esDataId := uuid.NewV4().String()
                    peraction := PerVideoPicture{LinkInfo{
                        msg.Push.PushId,
                        msg.Cid,
                        msg.Push.Cam.Addr,
                        msg.Push.Cam.Name,
                        i.Timestamp,
                        url,
                        msg.Tasklab.Taskid,
                        msg.Tasklab.Taskname,
                        sdkNames,
                        "",
                        alarmRules,
                        time.Now().Format("2006-01-02 15:04:05"),
                        "",
                        "",
                        "",
                        msg.Push.ServerId,
                        msg.Push.ServerName,
                        msg.Push.LocalIp,
                        "",
                        isAlarm,
                        false,
                        false,
                        false,
                        nil,
                        targetInfos,
                    },
                        linkTag,
                        linkTagInfos,
                    }
                    requstbody, err := json.Marshal(peraction)
                    if len(linkTagInfos) > 0 {
                        logger.Info("联动任务1111")
                    }
                    if err != nil {
                        logger.Info("json parse error ", err)
                        return
                    }
                    resp1, err2 := EsReq("POST", videoPersonUrl, requstbody)
                    if err2 != nil {
                        logger.Error("往ES插入数据失败", err)
                    } else {
                        logger.Debug("插入es返回的数据信息是(target):", resp1)
                        // 发出录像信号
                        ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: msg.Cid, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{"-1"}, Type: 2})
                        for index, link := range linkTagInfos {
                            logger.Info("联动任务的录像信号:", index)
                            ruleserver.AddLxMessage(&protomsg.VideotapeInfo{EsDataId: msg.Push.PushId, CameraId: link.CameraId, TaskId: msg.Tasklab.Taskid, VideoUrl: msg.Push.VideoUrl, ImgId: i.Id, SdkIds: []string{strconv.Itoa(index)}, Type: 2})
                        }
                        logger.Warn("__________________________________________往ES插入target数据成功")
                        //os.Exit(1)
                    }
                }
            } else {
                logger.Info("没有首次报警的目标,不插入")
            }
        }
    }
}
// 获取本机ip
func GetLocalIP() (ipv4 string, err error) {
    var (
        addrs   []net.Addr
        addr    net.Addr
        ipNet   *net.IPNet // IP地址
        isIpNet bool
    )
    // 获取所有网卡
    if addrs, err = net.InterfaceAddrs(); err != nil {
        return
    }
    // 取第一个非lo的网卡IP
    for _, addr = range addrs {
        // 这个网络地址是IP地址: ipv4, ipv6
        if ipNet, isIpNet = addr.(*net.IPNet); isIpNet && !ipNet.IP.IsLoopback() {
            // 跳过IPV6
            if ipNet.IP.To4() != nil {
                ipv4 = ipNet.IP.String() // 192.168.1.1
                return
            }
        }
    }
    err = errors.New("ipv4 not found")
    return
}
// 把报警等级转化成汉字
func ChangeToString(defenceState bool, i int32) string {
    alarm := ""
    if defenceState {
        if i == 1 {
            alarm = "一级"
        }
        if i == 2 {
            alarm = "二级"
        }
        if i == 3 {
            alarm = "三级"
        }
        if i == 4 {
            alarm = "四级"
        }
        if i == 5 {
            alarm = "五级"
        }
    } else {
        alarm = "撤防"
    }
    return alarm
}
func uploadImg(msg structure.ResultMsg) string {
    bdata, err := util.UnCompress(msg.Data)
    if err != nil {
        panic("解压缩图片时出现错误")
    }
    i := protomsg.Image{}
    err = proto.Unmarshal(bdata, &i)
    resp1, err1 := util.DrawPolygonOnImageForTarget(msg.Cid, i, msg.RuleResult["target"].([]structure.Result), weedfsUrl)
    f,err1 := p.Lookup("InsertToEs")
    if err1 != nil {
        logger.Error("缓存数据画框或上传图片服务器出错", err)
    } else {
        logger.Info("上传的图片信息:", resp1)
        panic("没有找到中间件的格式化数据函数")
    }
    if resp1["fileUrl"] != nil {
        return resp1["fileUrl"].(string)
    } else {
        return ""
    }
}
//获取年龄描述
func getDescription(age int32) string {
    ageInfo := "青年"
    if age > 0 && age < 7 {
        ageInfo = "童年"
    } else if age >= 7 && age < 18 {
        ageInfo = "少年"
    } else if age >= 18 && age < 40 {
        ageInfo = "青年"
    } else if age >= 40 && age < 65 {
        ageInfo = "中年"
    } else if age >= 65 {
        ageInfo = "老年"
    }
    return ageInfo
}
func getRaceString(i int32) string {
    race := ""
    if i == 1 {
        race = "白人"
    } else if i == 2 {
        race = "黄人"
    } else {
        race = "黑人"
    }
    return race
}
func Feature2Jsonstr(obj ObjAndRules) (string, string) {
    var lable string
    var lableAttach string
    switch obj.Type {
    case "face":
        sex := ""
        if obj.ThftRes.Gender == 1 {
            sex = "男"
        } else {
            sex = "女"
        }
        race := getRaceString(obj.ThftRes.Race)
        ageDescription := getDescription(obj.ThftRes.Age)
        lable = sex + "/" + ageDescription + "/" + race
        lableAttach = strconv.Itoa(int(obj.ThftRes.Age)) + "岁" + "/" + "微笑值:" + strconv.Itoa(int(obj.ThftRes.Smile)) + "/" + "颜值:" + strconv.Itoa(int(obj.ThftRes.Beauty))
    case "plate":
        // 车牌运动方向,0 unknown, 1 left, 2 right, 3 up, 4 down
        lable = obj.Car.License + "/" + cache.GetDic("nVehicleColor1"+strconv.Itoa(int(obj.Car.NVehicleColor1))) + "车辆" + "/" +
            cache.GetDic("nColor"+strconv.Itoa(int(obj.Car.NColor))) + "车牌"
        lableAttach = "车牌置信度:" + strconv.Itoa(int(obj.Car.NConfidence)) + "/" + "车的亮度:" + strconv.Itoa(int(obj.Car.NVehicleBright)) +"/"+ "车牌类型"+cache.GetDic("nType"+strconv.Itoa(int(obj.Car.NType)))+
            "车身辅颜色:"+cache.GetDic("nVehicleColor2"+strconv.Itoa(int(obj.Car.NVehicleColor2)))+"/"+"是否识别到车牌:"+cache.GetDic("nVehicleColor1"+strconv.Itoa(int(obj.Car.NVehicleColor1)))+"/"+
            "车辆置信度"+strconv.Itoa(int(obj.Score))+"/"+"品牌:" +obj.Car.VehicleType1
    }
    return lable, lableAttach
}
func msg2PersonVideo(msg structure.ResultMsg) *LinkInfo {
    if msg.RuleResult["yolo"] != nil && len(msg.RuleResult["yolo"].([]structure.Result)) > 0 {
        // 先判断一下数据带的规则标签是否有可以插入的
        flag := false
        for _, res := range msg.RuleResult["yolo"].([]structure.Result) {
            //logger.Info("定时器打的数字标签:",res.Others.TimeLabel)
            if res.Others.TimeLabel == "01" || res.Others.TimeLabel == "10" {
                flag = true
            }
        }
        if flag {
            logger.Info("插入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" {
                    // 拼出sdkname
                    //logger.Info("应该进来才对的")
                    sdkNames = sdkNames + yoloResult.SdkName
                    alarm := ChangeToString(yoloResult.DefenceState, yoloResult.AlarmLevel)
                    linkInfo := ""
                    if yoloResult.IsLink {
                        linkInfo = "联动任务"
                    }
                    alarmRules = append(alarmRules, AlarmRule{yoloResult.RuleGroupId, alarm, yoloResult.RuleText, yoloResult.DefenceState, linkInfo})
                    // 上传缓存数据的图片拿到url
                    if yoloResult.Others.CacheData != nil {
                        //InsertYolo(msg.RuleResult["cacheData"].(ruleserver.ResultMsg))
                        // 把缓存的数据上传后得到地址存进去
                        // 解压缩并上传图片
                        msgs := yoloResult.Others.CacheData
                        for _, msg1 := range msgs {
                            bdata, err := util.UnCompress(msg1.Data)
                            if err != nil {
                                panic("解压缩图片时出现错误")
                            }
                            i := protomsg.Image{}
                            err = proto.Unmarshal(bdata, &i)
                            resp1, err1 := util.DrawPolygonOnImageForYolo(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            if err1 != nil {
                                logger.Error("缓存数据画框或上传图片服务器出错", err)
                            } else {
                                logger.Info("上传的图片信息:", resp1)
                            }
                            if resp1["fileUrl"] != nil {
                                url = append(url, resp1["fileUrl"].(string))
                            }
                        }
                    }
                    // 装配目标信息数据
                    for _, target := range yoloResult.AlarmObj {
                        // 去重添加
                        var flag = true
                        for _, selectTarget := range targetInfos {
                            if target.Id == selectTarget.TargetId {
                                flag = false
                                break
                            }
                        }
                        if flag {
                            var target1 = new(Target)
                            target1.TargetId = target.Id
                            target1.TargetScore = target.Score
                            target1.TargetLocation = Points{TopLeft: Point{target.Location.X, target.Location.Y}, BottomRight: Point{target.Location.X + target.Location.Width, target.Location.Y + target.Location.Height}}
                            targetInfos = append(targetInfos, *target1)
                        }
                    }
                }
            }
            isAlarm := false
            resp := make(map[string]interface{})
            // 解压缩并上传图片
            bdata, err := util.UnCompress(msg.Data)
            if err != nil {
                panic("解压缩图片时出现错误")
            }
            i := protomsg.Image{}
            err = proto.Unmarshal(bdata, &i)
            if len(alarmRules) > 0 {
                isAlarm = true
                //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                resp, err = util.DrawPolygonOnImageForYolo(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                if err != nil {
                    logger.Error("画框或上传图片服务器出错", err)
                    return nil
                } else {
                    logger.Info("上传的图片信息:", resp)
                }
            } else {
                isAlarm = false
                // 不是报警数据不存
                return nil
            }
            if resp["fileUrl"] != nil {
                url = append(url, resp["fileUrl"].(string))
                //esDataId := uuid.NewV4().String()
                pervideo := &LinkInfo{
                    msg.Push.PushId + "-" + uuid.NewV4().String(),
                    msg.Cid,
                    msg.Push.Cam.Addr,
                    msg.Push.Cam.Name,
                    i.Timestamp,
                    []string{resp["fileUrl"].(string)},
                    msg.Tasklab.Taskid,
                    msg.Tasklab.Taskname,
                    "人脸",
                    "",
                    alarmRules,
                    time.Now().Format("2006-01-02 15:04:05"), // 只检测,没有比对时间
                    "",
                    "",
                    "",
                    msg.Push.ServerId,
                    msg.Push.ServerName,
                    msg.Push.LocalIp,
                    "",
                    isAlarm,
                    false,
                    false,
                    false,
                    nil,
                    targetInfos,
                }
                return pervideo
            } else {
                return nil
            }
        } else {
            logger.Debug("timeLabel条件都不符合!")
            return nil
        }
    } else {
        return nil
    }
    f.(func(msg structure.ResultMsg))(msg)
}