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}) } }