| | |
| | | "encoding/json" |
| | | "time" |
| | | |
| | | "gat1400Exchange/client" |
| | | "gat1400Exchange/config" |
| | | "gat1400Exchange/models" |
| | | "gat1400Exchange/nvcs" |
| | | "gat1400Exchange/pkg" |
| | | "gat1400Exchange/pkg/logger" |
| | | "gat1400Exchange/util" |
| | | "gat1400Exchange/vo" |
| | | |
| | | uuid "github.com/satori/go.uuid" |
| | | ) |
| | | |
| | | type CaptureRepository struct { |
| | |
| | | } |
| | | |
| | | func (c CaptureRepository) FaceForward(faceList []vo.FaceObject) { |
| | | var err error |
| | | |
| | | if faceList == nil || len(faceList) == 0 { |
| | | logger.Warn("FaceList is nil") |
| | | return |
| | |
| | | logger.Warn("SubImageInfoObject is nil") |
| | | continue |
| | | } |
| | | |
| | | var deviceId = face.DeviceID |
| | | var faceId = face.FaceID |
| | | var faceImageStr string |
| | | var bgImageStr string |
| | | var bgImageBytes, faceImageBytes []byte = nil, nil |
| | | |
| | | // 获取大图, 目前海康的小图分辨率太低 |
| | | for _, image := range face.SubImageList.SubImageInfoObject { |
| | | if len(image.Data) > len(faceImageStr) { |
| | | faceImageStr = image.Data |
| | | if image.Type != "14" { |
| | | continue |
| | | } |
| | | |
| | | if len(image.Data) > 0 { |
| | | if len(image.Data) > len(bgImageStr) { |
| | | bgImageStr = image.Data |
| | | } |
| | | } else if image.StoragePath != "" { |
| | | imgData, err := util.ImageDownload(image.StoragePath, nil) |
| | | if err != nil { |
| | | logger.Warn("Image download failure, %s", err.Error()) |
| | | } else { |
| | | bgImageBytes = imgData |
| | | bgImageStr = "///" |
| | | } |
| | | } |
| | | } |
| | | |
| | | if bgImageBytes == nil { |
| | | bgImageBytes, err = base64.StdEncoding.DecodeString(bgImageStr) |
| | | if err != nil { |
| | | logger.Warn("Decode Image Base64 String failure, %s", err.Error()) |
| | | continue |
| | | } |
| | | } |
| | | |
| | | // 判断图片类型是否为场景图, 根据人脸坐标切小图. |
| | | if config.ImageConf.CutFaceImage && face.LeftTopX != 0 { |
| | | faceRect := &pkg.Rect{ |
| | | Left: face.LeftTopX, |
| | | Top: face.LeftTopY, |
| | | Right: face.RightBtmX, |
| | | Bottom: face.RightBtmY, |
| | | } |
| | | |
| | | faceImageBytes, err = pkg.SubCutImage(bgImageBytes, faceRect, config.ImageConf.Enlarge) |
| | | if err != nil { |
| | | logger.Warn("Cut face image failure, %s", err.Error()) |
| | | } |
| | | } |
| | | |
| | | // 转发图像 |
| | | logger.Debug("Prepare forward image, deviceId:%s, image len:%d, server:%s", deviceId, len(faceImageStr), config.ForwardConf.SyncServer) |
| | | if deviceId != "" && faceImageStr != "" && config.ForwardConf.SyncServer != "" { |
| | | pd := c.PackPushDataV2(deviceId, faceId, faceImageStr, face.FaceAppearTime) |
| | | logger.Debug("Prepare forward image, deviceId:%s, bgImage len:%d, smImage len:%d server:%s", deviceId, len(bgImageBytes), len(faceImageBytes), config.ForwardConf.SyncServer) |
| | | if deviceId != "" && bgImageStr != "" && config.ForwardConf.SyncServer != "" { |
| | | pd := c.PackPushDataV2(deviceId, faceId, face.FaceAppearTime, bgImageBytes, faceImageBytes) |
| | | if pd == nil { |
| | | return |
| | | } |
| | | |
| | | // 处理梯控填写的楼层信息 暂时使用otherFeature字段 |
| | | if face.OtherFeature != "" && pd.CameraFloor == "" { |
| | | pd.Direction, pd.CameraFloor, _ = pkg.RestoreFloor(face.OtherFeature) |
| | | } |
| | | |
| | | payload, err := json.Marshal(pd) |
| | |
| | | |
| | | if !util.SendData(payload, config.ForwardConf.SyncServer) { |
| | | cacheItem, _ := json.Marshal(pd) |
| | | c.CacheData(cacheItem) |
| | | c.CacheData(cacheItem, "basic") |
| | | logger.Warn("The data forwarding failed, adding to local cache.") |
| | | } else { |
| | | logger.Debug("The data forwarding successful. deviceId:%s, picId:%s", deviceId, face.FaceID) |
| | | } |
| | | } |
| | | } |
| | | |
| | | return |
| | | } |
| | | |
| | | func (c CaptureRepository) PersonForward(personList []vo.PersonObject) { |
| | | var err error |
| | | |
| | | if personList == nil || len(personList) == 0 { |
| | | logger.Warn("FaceList is nil") |
| | | return |
| | | } |
| | | |
| | | for _, v := range personList { |
| | | if v.SubImageList.SubImageInfoObject == nil { |
| | | logger.Warn("SubImageInfoObject is nil") |
| | | continue |
| | | } |
| | | var deviceId = v.DeviceID |
| | | var targetId = v.PersonID |
| | | var bgImageStr string |
| | | var bgImageBytes, faceImageBytes []byte = nil, nil |
| | | |
| | | // 获取大图, 目前海康的小图分辨率太低 |
| | | for _, image := range v.SubImageList.SubImageInfoObject { |
| | | if image.Type != "14" { |
| | | continue |
| | | } |
| | | |
| | | if len(image.Data) > 0 { |
| | | if len(image.Data) > len(bgImageStr) { |
| | | bgImageStr = image.Data |
| | | } |
| | | } else if image.StoragePath != "" { |
| | | imgData, err := util.ImageDownload(image.StoragePath, nil) |
| | | if err != nil { |
| | | logger.Warn("Image download failure, %s", err.Error()) |
| | | } else { |
| | | bgImageBytes = imgData |
| | | bgImageStr = "///" |
| | | } |
| | | } |
| | | } |
| | | |
| | | if bgImageBytes == nil { |
| | | bgImageBytes, err = base64.StdEncoding.DecodeString(bgImageStr) |
| | | if err != nil { |
| | | logger.Warn("Decode Image Base64 String failure, %s", err.Error()) |
| | | continue |
| | | } |
| | | } |
| | | |
| | | // 转发图像 |
| | | logger.Debug("Prepare forward person image, deviceId:%s, image len:%d, server:%s", deviceId, len(bgImageBytes), config.ForwardConf.SyncServer) |
| | | if deviceId != "" && bgImageStr != "" && config.ForwardConf.SyncServer != "" { |
| | | pd := c.PackPushDataV2(deviceId, targetId, v.PersonAppearTime, bgImageBytes, faceImageBytes) |
| | | if pd == nil { |
| | | return |
| | | } |
| | | |
| | | // 处理梯控填写的楼层信息 暂时使用oherFeature字段 |
| | | if v.BehaviorDescription != "" { |
| | | pd.CameraFloor = v.BehaviorDescription |
| | | } |
| | | |
| | | //// 尝试从faceId提取楼层 |
| | | //if pd.CameraFloor == "" && config.ClientConf.AddFloorToFaceId { |
| | | // pd.CameraFloor, _ = pkg.ParseFloorFromId(v.PersonID) |
| | | //} |
| | | //logger.Debug("device %s, CameraFloor:%s", deviceId, pd.CameraFloor) |
| | | |
| | | payload, err := json.Marshal(pd) |
| | | if err != nil { |
| | | logger.Warn("Marshal error, %s", err.Error()) |
| | | return |
| | | } |
| | | |
| | | if !util.SendData(payload, config.ForwardConf.SyncServer) { |
| | | cacheItem, _ := json.Marshal(pd) |
| | | c.CacheData(cacheItem, "basic") |
| | | logger.Warn("The data forwarding failed, adding to local cache.") |
| | | } else { |
| | | logger.Debug("The data forwarding successful. deviceId:%s", deviceId) |
| | |
| | | return |
| | | } |
| | | |
| | | func (c CaptureRepository) PackPushData(deviceId, faceId, faceImage, appearTime string) *vo.PushDataInfo { |
| | | var pd = new(vo.PushDataInfo) |
| | | var device models.Device |
| | | |
| | | if err := device.FindById(deviceId); err != nil { |
| | | logger.Warn("Can't find device in database, device:%s, %s", deviceId, err.Error()) |
| | | return pd |
| | | } |
| | | |
| | | // 匹配楼层 |
| | | faceAppearTime, err := time.ParseInLocation("20060102150405", appearTime, time.Local) |
| | | if err != nil { |
| | | logger.Warn("Parse face appear time error, %s", err.Error()) |
| | | faceAppearTime = time.Now() |
| | | } |
| | | |
| | | // 电梯停止的时间 |
| | | devStopTime := time.Now().Format("2006-01-02 15:04:05") |
| | | var devPos models.Positions |
| | | _ = devPos.FindDevicePosition(deviceId, faceAppearTime.Unix()+5) // 加5秒电梯关门的时间 |
| | | if devPos.TimeString != "" { |
| | | devStopTime = devPos.TimeString |
| | | } |
| | | |
| | | imageBytes, err := base64.StdEncoding.DecodeString(faceImage) |
| | | if err != nil { |
| | | logger.Warn("Decode Image Base64 String failure, %s", err.Error()) |
| | | return pd |
| | | } |
| | | |
| | | pd.PicMaxImages = append(pd.PicMaxImages, imageBytes) |
| | | |
| | | tr := vo.TaskResultInfo{ |
| | | Id: uuid.NewV4().String(), |
| | | CameraId: deviceId, |
| | | CameraAddr: device.Addr + devPos.Pos, |
| | | CameraName: device.Name, |
| | | PicMaxUrl: []string{""}, |
| | | PicDate: faceAppearTime.Format("2006-01-02 15:04:05"), |
| | | LikeDate: devStopTime, |
| | | AnalyServerId: deviceId, |
| | | DataSource: "camera", |
| | | TargetInfo: []vo.TargetInfo{{TargetId: faceId}}, |
| | | } |
| | | |
| | | pd.SourceData = vo.ESInfo{ |
| | | TaskResultInfo: tr, |
| | | Version: "3.3", |
| | | UpdateTime: time.Now().Format("2006-01-02 15:04:05"), |
| | | } |
| | | |
| | | return pd |
| | | } |
| | | |
| | | func (c CaptureRepository) PackPushDataV2(deviceId, faceId, faceImage, appearTime string) *vo.PushDataInfoV2 { |
| | | func (c CaptureRepository) PackPushDataV2(deviceId, faceId, appearTime string, bgImgBytes, faceImgBytes []byte) *vo.PushDataInfoV2 { |
| | | var pd = new(vo.PushDataInfoV2) |
| | | var device models.Device |
| | | var floor string |
| | | var runDir string |
| | | |
| | | if err := device.FindById(deviceId); err != nil { |
| | | logger.Warn("Can't find device in database, device:%s, %s", deviceId, err.Error()) |
| | | return pd |
| | | } |
| | | |
| | | // 匹配楼层 |
| | | faceAppearTime, err := time.ParseInLocation("20060102150405", appearTime, time.Local) |
| | | if err != nil { |
| | | logger.Warn("Parse face appear time error, %s", err.Error()) |
| | | faceAppearTime = time.Now() |
| | | } |
| | | |
| | | var devPos models.Positions |
| | | _ = devPos.FindDevicePosition(deviceId, faceAppearTime.Unix()+5) // 加5秒电梯关门的时间 |
| | | if devPos.Pos == "" { |
| | | devPos.Pos = device.Pos |
| | | // 判断是否需要匹配楼层 |
| | | if config.NVCSConf.Model != "" { |
| | | runState := nvcs.FindPositionByTime(faceAppearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | floor = runState.Floor |
| | | |
| | | for i := 0; i < config.NVCSConf.WaitRunTime; i++ { |
| | | if runState = nvcs.FindMovePosition(faceAppearTime.Unix()+3, floor); runState.Floor != "" { |
| | | switch runState.RunState { |
| | | case nvcs.RunUp: |
| | | runDir = "in" |
| | | case nvcs.RunDown: |
| | | runDir = "out" |
| | | case nvcs.RunStop: |
| | | runDir = "" |
| | | } |
| | | |
| | | break |
| | | } |
| | | |
| | | time.Sleep(1 * time.Second) |
| | | } |
| | | } |
| | | |
| | | imageBytes, err := base64.StdEncoding.DecodeString(faceImage) |
| | | if err != nil { |
| | | logger.Warn("Decode Image Base64 String failure, %s", err.Error()) |
| | | return pd |
| | | pd.PicMaxImages = append(pd.PicMaxImages, bgImgBytes) |
| | | |
| | | if faceImgBytes != nil { |
| | | pd.PicSmImages = append(pd.PicSmImages, faceImgBytes) |
| | | } |
| | | |
| | | pd.PicMaxImages = append(pd.PicMaxImages, imageBytes) |
| | | pd.PicId = faceId |
| | | pd.PicDate = faceAppearTime.Format("2006-01-02 15:04:05") |
| | | pd.DataSource = "camera" |
| | | pd.CameraFloor = devPos.Pos |
| | | pd.CameraFloor = floor |
| | | pd.CameraId = deviceId |
| | | pd.Direction = runDir |
| | | |
| | | return pd |
| | | } |
| | | |
| | | func (c CaptureRepository) CacheData(payload []byte) { |
| | | func (c CaptureRepository) CacheData(payload []byte, msgType string) { |
| | | var cacheItem = models.Cache{ |
| | | Type: msgType, |
| | | Data: string(payload), |
| | | CreateTime: time.Now().Unix(), |
| | | Retry: 0, |
| | |
| | | |
| | | cacheItem.Save() |
| | | } |
| | | |
| | | func (c CaptureRepository) VIIDFaceMsgForward(msg *vo.RequestFaceList) { |
| | | faceInfo := msg.FaceListObject.FaceObject[0] |
| | | var floor, runDir string |
| | | |
| | | // 判断是否开启了梯控 |
| | | if config.NVCSConf.Model != "" { |
| | | // 匹配楼层 |
| | | faceAppearTime, err := time.ParseInLocation("20060102150405", faceInfo.FaceAppearTime, time.Local) |
| | | if err != nil { |
| | | logger.Warn("Parse face appear time error, %s", err.Error()) |
| | | faceAppearTime = time.Now() |
| | | } |
| | | |
| | | runState := nvcs.FindPositionByTime(faceAppearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | floor = runState.Floor |
| | | |
| | | for i := 0; i < config.NVCSConf.WaitRunTime; i++ { |
| | | if runState = nvcs.FindMovePosition(faceAppearTime.Unix()+3, floor); runState.Floor != "" { |
| | | switch runState.RunState { |
| | | case nvcs.RunUp: |
| | | runDir = "in" |
| | | case nvcs.RunDown: |
| | | runDir = "out" |
| | | case nvcs.RunStop: |
| | | runDir = "" |
| | | } |
| | | |
| | | break |
| | | } |
| | | |
| | | time.Sleep(1 * time.Second) |
| | | } |
| | | |
| | | for idx, _ := range msg.FaceListObject.FaceObject { |
| | | msg.FaceListObject.FaceObject[idx].OtherFeature, _ = pkg.ParseFloor(runDir, floor) |
| | | //if config.ClientConf.AddFloorToFaceId { |
| | | // msg.FaceListObject.FaceObject[idx].FaceID = pkg.GenerateFaceIdContainFloor(face.FaceID, devPos.Pos) |
| | | //} |
| | | } |
| | | } |
| | | |
| | | b, _ := json.Marshal(msg) |
| | | if client.FaceCapture(b) != vo.StatusSuccess { |
| | | cacheItem, _ := json.Marshal(msg) |
| | | c.CacheData(cacheItem, "1400-face") |
| | | logger.Warn("The data forwarding failed, adding to local cache.") |
| | | } |
| | | |
| | | return |
| | | } |
| | | |
| | | func (c CaptureRepository) VIIDPersonMsgForward(msg *vo.RequestPersonList) { |
| | | person := msg.PersonListObject.PersonObject[0] |
| | | // 匹配楼层 |
| | | appearTime, err := time.ParseInLocation("20060102150405", person.PersonAppearTime, time.Local) |
| | | if err != nil { |
| | | logger.Warn("Parse face appear time error, %s", err.Error()) |
| | | appearTime = time.Now() |
| | | } |
| | | |
| | | runState := nvcs.FindPositionByTime(appearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | |
| | | for idx, _ := range msg.PersonListObject.PersonObject { |
| | | msg.PersonListObject.PersonObject[idx].BehaviorDescription = runState.Floor |
| | | //if config.ClientConf.AddFloorToFaceId { |
| | | // msg.PersonListObject.PersonObject[idx].PersonID = pkg.GenerateFaceIdContainFloor(v.PersonID, devPos.Pos) |
| | | //} |
| | | } |
| | | |
| | | b, _ := json.Marshal(msg) |
| | | if client.PersonCapture(b) != vo.StatusSuccess { |
| | | cacheItem, _ := json.Marshal(msg) |
| | | c.CacheData(cacheItem, "1400-person") |
| | | logger.Warn("The data forwarding failed, adding to local cache.") |
| | | } |
| | | |
| | | return |
| | | } |
| | | |
| | | func (c CaptureRepository) PubRecordMessage(deviceId, msgId string) { |
| | | var msg = vo.RecordMsg{ |
| | | CamId: deviceId, |
| | | MsgId: msgId, |
| | | } |
| | | |
| | | logger.Debug("Pub record message %s, %s", deviceId, msgId) |
| | | body, _ := json.Marshal(&msg) |
| | | |
| | | _, err := util.HttpPost(config.ForwardConf.RecordServer, nil, body) |
| | | if err != nil { |
| | | logger.Warn(err.Error()) |
| | | } |
| | | } |