156 lines
4.3 KiB
Go
156 lines
4.3 KiB
Go
|
package ci
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"joylink.club/bj-rtsts-server/config"
|
||
|
"joylink.club/bj-rtsts-server/third_party/axle_device"
|
||
|
"joylink.club/bj-rtsts-server/third_party/message"
|
||
|
"sort"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type CiServer interface {
|
||
|
Start()
|
||
|
Stop()
|
||
|
//SendSectionReset 向计轴设备发送计轴命令
|
||
|
SendSectionReset(sectionId string, drst bool, pdrst bool)
|
||
|
//HandleSectionStatus 收到来自计轴设备的物理区段状态
|
||
|
HandleSectionStatus(status []*message.SectionStatusMsg)
|
||
|
}
|
||
|
|
||
|
// 北京12号线酒仙桥集中站物理区段码表
|
||
|
var codePointMap = map[int]string{0: "北京_12_酒仙桥_9G", 1: "北京_12_酒仙桥_1DG", 2: "北京_12_酒仙桥_11G", 3: "北京_12_酒仙桥_13G", 4: "北京_12_酒仙桥_15G", 5: "北京_12_酒仙桥_6G", 6: "北京_12_酒仙桥_8G", 7: "北京_12_酒仙桥_2DG", 8: "北京_12_酒仙桥_10G", 9: "北京_12_酒仙桥_12G", 10: "北京_12_酒仙桥_14G"}
|
||
|
var idRowMap = make(map[string]int)
|
||
|
var sectionCmds []*message.SectionCmdMsg
|
||
|
var cmdsLock = sync.Mutex{}
|
||
|
|
||
|
// rssp 测试
|
||
|
type ciServer struct {
|
||
|
//所属城市
|
||
|
city string
|
||
|
//所属线路
|
||
|
lineId string
|
||
|
//所属集中站
|
||
|
centralizedStation string
|
||
|
//接收方每个安全通信会话对应的发送周期值,单位ms
|
||
|
sendingPeriod uint32
|
||
|
//主安全通道
|
||
|
rsspChannel *axle_device.RsspChannel
|
||
|
//
|
||
|
cancel context.CancelFunc
|
||
|
}
|
||
|
|
||
|
func (s *ciServer) HandleSectionStatus(status []*message.SectionStatusMsg) {
|
||
|
if len(codePointMap) != len(status) {
|
||
|
fmt.Println("==>>接收到的区段状态与码表不对应:", "codePointsLen=", len(codePointMap), ",statusLen=", len(status))
|
||
|
return
|
||
|
}
|
||
|
fmt.Println("==>>接收到的区段状态----------------------------------------------------------------------------i")
|
||
|
for row, state := range status {
|
||
|
sectionId := codePointMap[row]
|
||
|
fmt.Printf("==>>[%d]区段[%s]状态: Clr=%t Occ=%t Rac=%t Rjo=%t Rjt=%t\n", row, sectionId, state.Clr, state.Occ, state.Rac, state.Rjo, state.Rjt)
|
||
|
}
|
||
|
fmt.Println("==>>接收到的区段状态----------------------------------------------------------------------------o")
|
||
|
}
|
||
|
func (s *ciServer) periodRun(runContext context.Context) {
|
||
|
defer func() {
|
||
|
fmt.Println("==>>CI Server 周期运行退出 ...")
|
||
|
}()
|
||
|
for {
|
||
|
select {
|
||
|
case <-runContext.Done():
|
||
|
return
|
||
|
default:
|
||
|
}
|
||
|
s.doSendSectionCmdMsg()
|
||
|
time.Sleep(time.Duration(s.sendingPeriod) * time.Millisecond)
|
||
|
//更新周期性参数
|
||
|
s.rsspChannel.NextPeriod()
|
||
|
}
|
||
|
}
|
||
|
func (s *ciServer) doSendSectionCmdMsg() {
|
||
|
if s.rsspChannel != nil {
|
||
|
data := s.collectSectionCmdsData()
|
||
|
fmt.Println("==>>CI发送区段指令数据", ",len=", len(data))
|
||
|
s.rsspChannel.SendUserData(data)
|
||
|
}
|
||
|
}
|
||
|
func (s *ciServer) collectSectionCmdsData() []byte {
|
||
|
defer func() {
|
||
|
cmdsLock.Unlock()
|
||
|
}()
|
||
|
cmdsLock.Lock()
|
||
|
//
|
||
|
data := (&message.SectionCmdMsgPack{Ck: 0x80, Scs: sectionCmds}).Encode()
|
||
|
return data
|
||
|
}
|
||
|
|
||
|
// SendSectionReset 发送区段复位指令
|
||
|
func (s *ciServer) SendSectionReset(sectionId string, drst bool, pdrst bool) {
|
||
|
defer func() {
|
||
|
cmdsLock.Unlock()
|
||
|
}()
|
||
|
cmdsLock.Lock()
|
||
|
//
|
||
|
sec := sectionCmds[idRowMap[sectionId]]
|
||
|
sec.Drst = drst
|
||
|
sec.Pdrst = pdrst
|
||
|
}
|
||
|
|
||
|
type rowId struct {
|
||
|
row int
|
||
|
id string
|
||
|
}
|
||
|
|
||
|
func (s *ciServer) Start() {
|
||
|
s.rsspChannel.SetRcvUserDataCallback(s.rcvUserData)
|
||
|
s.rsspChannel.Start()
|
||
|
ctx, cancel := context.WithCancel(context.Background())
|
||
|
go s.periodRun(ctx)
|
||
|
s.cancel = cancel
|
||
|
}
|
||
|
func (s *ciServer) Stop() {
|
||
|
if s.rsspChannel != nil {
|
||
|
s.rsspChannel.Stop()
|
||
|
s.rsspChannel = nil
|
||
|
}
|
||
|
if s.cancel != nil {
|
||
|
s.cancel()
|
||
|
}
|
||
|
}
|
||
|
func (s *ciServer) rcvUserData(data []byte) {
|
||
|
fmt.Println("==>>CI接收到区段状态数据", ",len=", len(data))
|
||
|
msg := &message.SectionStatusMsgPack{}
|
||
|
msg.Decode(data)
|
||
|
s.HandleSectionStatus(msg.Sms)
|
||
|
}
|
||
|
func NewRsspCiServer(cfg *config.RsspAxleConfig) CiServer {
|
||
|
ra := &ciServer{}
|
||
|
//
|
||
|
ra.city = cfg.City
|
||
|
ra.lineId = cfg.LineId
|
||
|
ra.centralizedStation = cfg.CentralizedStation
|
||
|
ra.sendingPeriod = cfg.RsspCfg.SendingPeriod
|
||
|
//
|
||
|
mrc := &axle_device.RsspChannel{}
|
||
|
ra.rsspChannel = mrc.Init(&cfg.RsspCfg)
|
||
|
//
|
||
|
return ra
|
||
|
}
|
||
|
|
||
|
func InitCiServerCodePoints() {
|
||
|
var ris []*rowId
|
||
|
for row, id := range codePointMap {
|
||
|
idRowMap[id] = row
|
||
|
ris = append(ris, &rowId{row: row, id: id})
|
||
|
}
|
||
|
sort.SliceStable(ris, func(i, j int) bool {
|
||
|
return ris[i].row < ris[j].row
|
||
|
})
|
||
|
for range ris {
|
||
|
sectionCmds = append(sectionCmds, &message.SectionCmdMsg{Drst: false, Pdrst: false})
|
||
|
}
|
||
|
}
|