package nvcs
|
|
import (
|
"container/list"
|
"fmt"
|
"time"
|
|
"gat1400Exchange/config"
|
"gat1400Exchange/models"
|
"gat1400Exchange/pkg/logger"
|
)
|
|
type simpleCache struct {
|
data *list.List
|
expiration time.Duration
|
}
|
|
func newCache(expiration time.Duration) *simpleCache {
|
return &simpleCache{
|
data: list.New(),
|
expiration: expiration,
|
}
|
}
|
|
// 存储数据到缓存中
|
func (c *simpleCache) store(data ElevatorRunData) {
|
var floorChanged = true
|
|
// 取RFID楼层
|
if config.RFIDConf.ReadFloor && gRFIDFloor != data.Floor {
|
if data.RunState == RunStop {
|
logger.Warn("A floor error has occurred rfid epc %s, nvcs floor %s", gRFIDFloor, data.Floor)
|
}
|
|
data.Floor = gRFIDFloor
|
}
|
|
if data.Floor == "" {
|
return
|
}
|
|
lastData := c.data.Back()
|
|
// 如果楼层相同,并且数据在1秒内,则忽略
|
if lastData != nil {
|
if lastData.Value.(ElevatorRunData).Floor == data.Floor {
|
floorChanged = false
|
if lastData.Value.(ElevatorRunData).Timestamp == data.Timestamp {
|
return
|
}
|
}
|
}
|
|
c.data.PushBack(data)
|
|
if !floorChanged {
|
return
|
}
|
|
// 数据库保存一份
|
var d = models.Positions{
|
DeviceId: data.Device,
|
Pos: data.Floor,
|
RunDir: data.RunState,
|
CreateTime: time.Now().Unix(),
|
TimeString: time.Now().Format("2006-01-02 15:04:05"),
|
}
|
|
err := d.Save()
|
if err != nil {
|
logger.Warn("Device position update error:%s", err.Error())
|
}
|
|
// 写OSD
|
var runStateStr string
|
if config.NVCSConf.RunState {
|
if data.RunState == RunUp {
|
runStateStr = "上"
|
} else if data.RunState == RunDown {
|
runStateStr = "下"
|
}
|
}
|
|
// 设置osd 格式 "1F上 固 枪"
|
if config.NVCSConf.OSD != "" {
|
floorText := fmt.Sprintf("%s%s %s", data.Floor, runStateStr, config.NVCSConf.OSD)
|
|
// 调用hik api 将文字添加到osd的左下角
|
err = addFloorToOSD(floorText)
|
if err != nil {
|
logger.Warn("%s", err.Error())
|
}
|
}
|
}
|
|
// 删除过期数据
|
func (c *simpleCache) cleanExpired() {
|
now := time.Now()
|
|
// 从队列头部开始检查是否有过期数据
|
for c.data.Len() > 0 {
|
elem := c.data.Front() // 获取队列头部的元素
|
item := elem.Value.(ElevatorRunData)
|
if now.Sub(time.Unix(item.Timestamp, 0)) > c.expiration {
|
// 如果数据已经过期,则从队列中删除
|
c.data.Remove(elem)
|
} else {
|
// 因为数据按时间顺序存储,遇到不过期的数据后就可以停止检查
|
break
|
}
|
}
|
}
|
|
func (c *simpleCache) getPositionByTime(timestamp int64) (runData ElevatorRunData) {
|
node := c.data.Back() // 从链表尾部开始
|
for node != nil {
|
if data, ok := node.Value.(ElevatorRunData); ok {
|
if data.Timestamp < timestamp {
|
runData = data
|
break
|
} else {
|
node = node.Prev() // 向前移动节点
|
}
|
|
} else {
|
break
|
}
|
}
|
|
logger.Debug("getPositionByTime %v ,time %d", runData, timestamp)
|
if node == nil {
|
fmt.Printf("get position failuer, query time %d cache len %d", timestamp, c.data.Len())
|
if c.data.Back() != nil {
|
logger.Warn("last node %+v", c.data.Back().Value)
|
}
|
}
|
|
return
|
}
|
|
func (c *simpleCache) getMovePosition(timestamp int64, floor string) (runData ElevatorRunData) {
|
logger.Debug("getMovePosition")
|
node := c.data.Back() // 从链表末尾开始
|
|
// 找到最近的符合时间戳的节点
|
for node != nil {
|
if data, ok := node.Value.(ElevatorRunData); ok {
|
if data.Timestamp >= timestamp {
|
node = node.Prev() // 向前移动节点
|
} else {
|
break
|
}
|
} else {
|
break
|
}
|
}
|
|
// 如果找到的节点的时间戳符合要求,继续检查楼层
|
if node != nil {
|
if current, ok := node.Value.(ElevatorRunData); ok && current.Timestamp >= timestamp {
|
for node != nil {
|
if nextNode := node.Next(); nextNode != nil {
|
logger.Debug("next node %v", nextNode.Value.(ElevatorRunData))
|
if nextData, ok := nextNode.Value.(ElevatorRunData); ok {
|
if nextData.Floor == floor {
|
node = nextNode // 向前移动节点
|
} else {
|
break
|
}
|
}
|
} else {
|
break
|
}
|
}
|
|
// 如果找到的楼层与目标楼层不同,返回该数据
|
if current.Floor != floor {
|
runData = current
|
}
|
}
|
}
|
|
return
|
}
|