zhangzengfei
2024-10-20 c1d32ecdb36d7365a660ae2cf1405e1ca1898b4b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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() // 从链表尾部开始
    if node == nil {
        return
    }
 
    for node != nil {
        if data, ok := node.Value.(ElevatorRunData); ok {
            if data.Timestamp >= timestamp {
                runData = data
                node = node.Prev() // 向前移动节点
            } else {
                break
            }
        } else {
            break
        }
    }
 
    return
}
 
func (c *simpleCache) getMovePosition(timestamp int64, floor string) (runData ElevatorRunData) {
    node := c.data.Back() // 从链表末尾开始
    if node == nil {
        return
    }
 
    // 找到最近的符合时间戳的节点
    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 {
                    if nextData, ok := nextNode.Value.(ElevatorRunData); ok {
                        if nextData.Floor == floor {
                            node = nextNode // 向前移动节点
                        } else {
                            break
                        }
                    }
                } else {
                    break
                }
            }
 
            // 如果找到的楼层与目标楼层不同,返回该数据
            if current.Floor != floor {
                runData = current
            }
        }
    }
 
    return
}