| | |
| | | elevator.Name = "1" |
| | | } |
| | | |
| | | var runState = elevatorRunData{ |
| | | var runState = ElevatorRunData{ |
| | | Device: elevator.Name, |
| | | Timestamp: time.Now().Unix(), |
| | | Floor: elevator.Status.FloorName, |
| | |
| | | iRunState = RunDown |
| | | } |
| | | |
| | | var runState = elevatorRunData{ |
| | | var runState = ElevatorRunData{ |
| | | Device: req.Id, |
| | | Timestamp: time.Now().Unix(), |
| | | Floor: req.State.Floor, |
| | |
| | | |
| | | floor := fmt.Sprintf("%dF", req.Floor) |
| | | |
| | | var runState = elevatorRunData{ |
| | | var runState = ElevatorRunData{ |
| | | Device: req.Id, |
| | | Timestamp: time.Now().Unix(), |
| | | Floor: floor, |
| | |
| | | } |
| | | |
| | | // 存储数据到缓存中 |
| | | func (c *simpleCache) store(data elevatorRunData) { |
| | | func (c *simpleCache) store(data ElevatorRunData) { |
| | | var floorChanged = true |
| | | |
| | | // 取RFID楼层 |
| | |
| | | data.Floor = gRFIDFloor |
| | | } |
| | | |
| | | if data.Floor == "" { |
| | | return |
| | | } |
| | | |
| | | lastData := c.data.Back() |
| | | |
| | | // 如果楼层相同,并且数据在1秒内,则忽略 |
| | | if lastData != nil { |
| | | if lastData.Value.(elevatorRunData).Floor == data.Floor { |
| | | if lastData.Value.(ElevatorRunData).Floor == data.Floor { |
| | | floorChanged = false |
| | | if lastData.Value.(elevatorRunData).Timestamp == data.Timestamp { |
| | | if lastData.Value.(ElevatorRunData).Timestamp == data.Timestamp { |
| | | return |
| | | } |
| | | } |
| | |
| | | floorText := fmt.Sprintf("%s%s %s", data.Floor, runStateStr, config.NVCSConf.OSD) |
| | | |
| | | // 调用hik api 将文字添加到osd的左下角 |
| | | addFloorToOSD(floorText) |
| | | err = addFloorToOSD(floorText) |
| | | if err != nil { |
| | | logger.Warn("%s", err.Error()) |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | // 删除过期数据 |
| | |
| | | // 从队列头部开始检查是否有过期数据 |
| | | for c.data.Len() > 0 { |
| | | elem := c.data.Front() // 获取队列头部的元素 |
| | | item := elem.Value.(elevatorRunData) |
| | | item := elem.Value.(ElevatorRunData) |
| | | if now.Sub(time.Unix(item.Timestamp, 0)) > c.expiration { |
| | | // 如果数据已经过期,则从队列中删除 |
| | | c.data.Remove(elem) |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | func (c *simpleCache) getPositionByTime(timestamp int64) (runData ElevatorRunData) { |
| | | node := c.data.Back() |
| | | if node == nil { |
| | | return |
| | | } |
| | | |
| | | for { |
| | | if node.Prev() == nil { |
| | | break |
| | | } |
| | | |
| | | if node.Prev().Value.(ElevatorRunData).Timestamp >= timestamp { |
| | | node = node.Prev() |
| | | } else { |
| | | break |
| | | } |
| | | } |
| | | |
| | | if node.Value.(ElevatorRunData).Timestamp >= timestamp { |
| | | runData = node.Value.(ElevatorRunData) |
| | | } |
| | | |
| | | return |
| | | } |
| | | |
| | | func (c *simpleCache) getMovePosition(timestamp int64, floor string) (runData ElevatorRunData) { |
| | | node := c.data.Back() |
| | | if node == nil { |
| | | return |
| | | } |
| | | |
| | | // 先找到最近节点 |
| | | for { |
| | | if node.Prev() == nil { |
| | | break |
| | | } |
| | | |
| | | if node.Prev().Value.(ElevatorRunData).Timestamp >= timestamp { |
| | | node = node.Prev() |
| | | } else { |
| | | break |
| | | } |
| | | } |
| | | |
| | | if node.Value.(ElevatorRunData).Timestamp >= timestamp { |
| | | for { |
| | | if node.Next() == nil { |
| | | break |
| | | } |
| | | |
| | | if node.Next().Value.(ElevatorRunData).Floor == floor { |
| | | node = node.Next() |
| | | } else { |
| | | break |
| | | } |
| | | } |
| | | } |
| | | |
| | | if node.Value.(ElevatorRunData).Timestamp >= timestamp && |
| | | node.Next().Value.(ElevatorRunData).Floor != floor { |
| | | runData = node.Value.(ElevatorRunData) |
| | | } |
| | | |
| | | return |
| | | } |
| | |
| | | ) |
| | | |
| | | // 数据结构 |
| | | type elevatorRunData struct { |
| | | type ElevatorRunData struct { |
| | | Device string |
| | | Timestamp int64 |
| | | Floor string |
| | |
| | | return "", 0 |
| | | } |
| | | |
| | | return runState.(elevatorRunData).Floor, runState.(elevatorRunData).RunState |
| | | return runState.(ElevatorRunData).Floor, runState.(ElevatorRunData).RunState |
| | | } |
| | | |
| | | func FindPositionByTime(timestamp int64) ElevatorRunData { |
| | | return cache.getPositionByTime(timestamp) |
| | | } |
| | | |
| | | func FindMovePosition(timestamp int64, floor string) ElevatorRunData { |
| | | return cache.getMovePosition(timestamp, floor) |
| | | } |
| | | |
| | | func listenQueue() { |
| | | for { |
| | | data := queue.get() |
| | | |
| | | //t := time.Now() |
| | | cache.store(data) |
| | | |
| | | //logger.Debug("process queue data %+v, use time %v", data, time.Since(t)) |
| | | |
| | | // 清理过期数据 |
| | | cache.cleanExpired() |
| | | } |
| | |
| | | |
| | | import ( |
| | | "encoding/xml" |
| | | "fmt" |
| | | "io/ioutil" |
| | | |
| | | "gat1400Exchange/pkg/logger" |
| | | |
| | | dac "github.com/xinsnake/go-http-digest-auth-client" |
| | | ) |
| | |
| | | cameraWebPassword = "a1234567" |
| | | ) |
| | | |
| | | var overlayText textOverlay |
| | | var overlayText TextOverlay |
| | | |
| | | type textOverlay struct { |
| | | type TextOverlay struct { |
| | | Id int64 `xml:"id"` |
| | | Enabled bool `xml:"enabled"` |
| | | PositionX int64 `xml:"positionX"` |
| | |
| | | return ioutil.ReadAll(resp.Body) |
| | | } |
| | | |
| | | func addFloorToOSD(osdText string) { |
| | | func addFloorToOSD(osdText string) error { |
| | | overlay7Url := cameraWebAddr + hikISAPIOverlay7SetUrl |
| | | |
| | | // 获取左下角第一个字符的位置 |
| | | if overlayText.DisplayText == "" { |
| | | rsp, err := hikISAPIRequest(cameraWebUser, cameraWebPassword, "GET", overlay7Url, "") |
| | | if err != nil { |
| | | logger.Warn("Get osd info failure") |
| | | return |
| | | return fmt.Errorf("get osd info. %s", err.Error()) |
| | | } |
| | | |
| | | err = xml.Unmarshal(rsp, &overlayText) |
| | | if err != nil { |
| | | logger.Warn("%s", err.Error()) |
| | | return |
| | | return fmt.Errorf("xml unmarshal. %s", err.Error()) |
| | | } |
| | | } |
| | | |
| | | if overlayText.DisplayText == osdText { |
| | | return |
| | | return nil |
| | | } |
| | | |
| | | overlayText.DisplayText = osdText |
| | | body, _ := xml.Marshal(overlayText) |
| | | _, err := hikISAPIRequest(cameraWebUser, cameraWebPassword, "PUT", overlay7Url, string(body)) |
| | | if err != nil { |
| | | logger.Warn("Camera osd set failure!!") |
| | | return |
| | | return fmt.Errorf("set osd. %s", err.Error()) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | |
| | | package nvcs |
| | | |
| | | type chQueue struct { |
| | | data chan elevatorRunData |
| | | data chan ElevatorRunData |
| | | } |
| | | |
| | | func newChQueue(size int) *chQueue { |
| | | return &chQueue{ |
| | | data: make(chan elevatorRunData, size), |
| | | data: make(chan ElevatorRunData, size), |
| | | } |
| | | } |
| | | |
| | | func (q *chQueue) put(data elevatorRunData) { |
| | | func (q *chQueue) put(data ElevatorRunData) { |
| | | q.data <- data |
| | | } |
| | | |
| | | func (q *chQueue) get() elevatorRunData { |
| | | func (q *chQueue) get() ElevatorRunData { |
| | | data := <-q.data |
| | | return data |
| | | } |
| | |
| | | if floor != gRFIDFloor { |
| | | gRFIDFloor = floor |
| | | logger.Debug("rfid read epc floor %s", gRFIDFloor) |
| | | } |
| | | |
| | | cacheData := cache.data.Back() |
| | | if cacheData != nil { |
| | | runState := cacheData.Value.(ElevatorRunData) |
| | | runState.Floor = floor |
| | | runState.Timestamp = time.Now().Unix() |
| | | runState.Device = "rfid-reader" |
| | | |
| | | queue.put(runState) |
| | | } |
| | | } |
| | | } else { |
| | | gRFIDFloor = "" |
| | | } |
| | | |
| | | time.Sleep(200 * time.Millisecond) |
| | |
| | | import ( |
| | | "encoding/base64" |
| | | "encoding/json" |
| | | "gat1400Exchange/nvcs" |
| | | "time" |
| | | |
| | | "gat1400Exchange/client" |
| | | "gat1400Exchange/config" |
| | | "gat1400Exchange/models" |
| | | "gat1400Exchange/nvcs" |
| | | "gat1400Exchange/pkg" |
| | | "gat1400Exchange/pkg/logger" |
| | | "gat1400Exchange/util" |
| | |
| | | |
| | | // 判断是否需要匹配楼层 |
| | | if config.NVCSConf.Model != "" { |
| | | // 匹配楼层 |
| | | var devPos models.Positions |
| | | _ = devPos.FindDevicePosition(deviceId, faceAppearTime.Unix()+5) // 加5秒电梯关门的时间 |
| | | |
| | | floor = devPos.Pos |
| | | runState := nvcs.FindPositionByTime(faceAppearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | floor = runState.Floor |
| | | |
| | | for i := 0; i < config.NVCSConf.WaitRunTime; i++ { |
| | | var dbPos models.Positions |
| | | if err := dbPos.FindMovePosition(faceAppearTime.Unix()+5, floor); err == nil { |
| | | switch dbPos.RunDir { |
| | | if runState = nvcs.FindMovePosition(faceAppearTime.Unix()+3, floor); runState.Floor != "" { |
| | | switch runState.RunState { |
| | | case nvcs.RunUp: |
| | | runDir = "in" |
| | | case nvcs.RunDown: |
| | |
| | | |
| | | func (c CaptureRepository) VIIDFaceMsgForward(msg *vo.RequestFaceList) { |
| | | faceInfo := msg.FaceListObject.FaceObject[0] |
| | | var floor, runDir string |
| | | |
| | | // 判断是否开启了梯控 |
| | | if config.NVCSConf.Model != "" { |
| | |
| | | faceAppearTime = time.Now() |
| | | } |
| | | |
| | | var floor, runDir string |
| | | var devPos models.Positions |
| | | _ = devPos.FindPositionByTime(faceAppearTime.Unix() + 5) // 加5秒电梯关门的时间 |
| | | if devPos.Pos == "" { |
| | | devPos.Pos = "1F" |
| | | } |
| | | |
| | | floor = devPos.Pos |
| | | runState := nvcs.FindPositionByTime(faceAppearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | floor = runState.Floor |
| | | |
| | | for i := 0; i < config.NVCSConf.WaitRunTime; i++ { |
| | | var dbPos models.Positions |
| | | if err := dbPos.FindMovePosition(faceAppearTime.Unix()+5, floor); err == nil { |
| | | switch dbPos.RunDir { |
| | | if runState = nvcs.FindMovePosition(faceAppearTime.Unix()+3, floor); runState.Floor != "" { |
| | | switch runState.RunState { |
| | | case nvcs.RunUp: |
| | | runDir = "1" |
| | | runDir = "in" |
| | | case nvcs.RunDown: |
| | | runDir = "2" |
| | | runDir = "out" |
| | | case nvcs.RunStop: |
| | | runDir = "0" |
| | | runDir = "" |
| | | } |
| | | |
| | | break |
| | |
| | | // msg.FaceListObject.FaceObject[idx].FaceID = pkg.GenerateFaceIdContainFloor(face.FaceID, devPos.Pos) |
| | | //} |
| | | } |
| | | |
| | | } |
| | | |
| | | b, _ := json.Marshal(msg) |
| | |
| | | appearTime = time.Now() |
| | | } |
| | | |
| | | var devPos models.Positions |
| | | _ = devPos.FindPositionByTime(appearTime.Unix() + 5) // 加5秒电梯关门的时间 |
| | | if devPos.Pos == "" { |
| | | devPos.Pos = "1F" |
| | | } |
| | | runState := nvcs.FindPositionByTime(appearTime.Unix() + 3) // 加3秒电梯关门的时间 |
| | | |
| | | for idx, _ := range msg.PersonListObject.PersonObject { |
| | | msg.PersonListObject.PersonObject[idx].BehaviorDescription = devPos.Pos |
| | | msg.PersonListObject.PersonObject[idx].BehaviorDescription = runState.Floor |
| | | //if config.ClientConf.AddFloorToFaceId { |
| | | // msg.PersonListObject.PersonObject[idx].PersonID = pkg.GenerateFaceIdContainFloor(v.PersonID, devPos.Pos) |
| | | //} |