diff --git a/api/simulation.go b/api/simulation.go index a866e26..d9809f9 100644 --- a/api/simulation.go +++ b/api/simulation.go @@ -4,6 +4,7 @@ import ( "fmt" "log/slog" "net/http" + "sort" "strconv" jwt "github.com/appleboy/gin-jwt/v2" @@ -45,6 +46,7 @@ func initPublishMapInfo() { if err != nil { panic("地图加载出错") } + sort.SliceStable(mapArr, func(i, j int) bool { return mapArr[i].Type != 0 }) for _, v := range mapArr { memory.PublishMapVerifyStructure(v) } @@ -273,10 +275,7 @@ func signalOperation(c *gin.Context) { } // simulation := checkDeviceDataAndReturn(req.SimulationId) slog.Info("传入状态参数", req) - // memory.ChangeSignalState(simulation, &state.SignalState{ - // Id: req.DeviceId, - // Aspect: req.Aspect, - // }, req.MapId) + memory.ChangeSignalState(simulation, req.MapId, req.DeviceId, req.Aspect) c.JSON(http.StatusOK, "ok") } diff --git a/ats/verify/simulation/wayside/memory/wayside_memory_map_init.go b/ats/verify/simulation/wayside/memory/wayside_memory_map_init.go index d7d30e2..a0c8a50 100644 --- a/ats/verify/simulation/wayside/memory/wayside_memory_map_init.go +++ b/ats/verify/simulation/wayside/memory/wayside_memory_map_init.go @@ -2,6 +2,7 @@ package memory import ( "fmt" + "strconv" "sync" "joylink.club/bj-rtsts-server/ats/verify/protos/graphicData" @@ -28,9 +29,8 @@ type stationUidStructure struct { SlopeIds map[string]*elementIdStructure CurvatureIds map[string]*elementIdStructure ButtonIds map[string]*elementIdStructure - LightIds map[string]*elementIdStructure - AlarmIds map[string]*elementIdStructure StationIds map[string]*elementIdStructure + IBPIds map[string]*elementIdStructure } type relayUidStructure struct { @@ -38,6 +38,13 @@ type relayUidStructure struct { RelayIds map[string]*elementIdStructure } +// 获取继电器的关联关系 +type deviceRelateUidPriex struct { + deviceCode string + typeCode string + isStation bool +} + // 获取UID的前缀信息 func getUIdPrefix(prefix interface{}) (string, string, string) { switch p := prefix.(type) { @@ -57,19 +64,22 @@ func getUIdPrefix(prefix interface{}) (string, string, string) { } // 初始化平面布置图 UID -func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStructure { +func initStationUid(data *graphicData.RtssGraphicStorage) *stationUidStructure { gus := &stationUidStructure{ - AxlePointIds: make(map[string]*elementIdStructure, len(graphicData.AxleCountings)), - TurnoutIds: make(map[string]*elementIdStructure, len(graphicData.Turnouts)), - PhysicalSectionIds: make(map[string]*elementIdStructure, len(graphicData.Section)), - SignalIds: make(map[string]*elementIdStructure, len(graphicData.Signals)), - TransponderIds: make(map[string]*elementIdStructure, len(graphicData.Transponders)), - SlopeIds: make(map[string]*elementIdStructure, len(graphicData.Slopes)), - CurvatureIds: make(map[string]*elementIdStructure, len(graphicData.Curvatures)), + AxlePointIds: make(map[string]*elementIdStructure, len(data.AxleCountings)), + TurnoutIds: make(map[string]*elementIdStructure, len(data.Turnouts)), + PhysicalSectionIds: make(map[string]*elementIdStructure, len(data.Section)), + SignalIds: make(map[string]*elementIdStructure, len(data.Signals)), + TransponderIds: make(map[string]*elementIdStructure, len(data.Transponders)), + SlopeIds: make(map[string]*elementIdStructure, len(data.Slopes)), + CurvatureIds: make(map[string]*elementIdStructure, len(data.Curvatures)), + ButtonIds: make(map[string]*elementIdStructure, len(data.EsbButtons)), + StationIds: make(map[string]*elementIdStructure, len(data.Stations)), + IBPIds: make(map[string]*elementIdStructure, len(data.Stations)), } - city, lineId, _ := getUIdPrefix(graphicData.UniqueIdPrefix) + city, lineId, _ := getUIdPrefix(data.UniqueIdPrefix) // 初始化计轴信息 - for _, a := range graphicData.AxleCountings { + for _, a := range data.AxleCountings { gus.AxlePointIds[a.Common.Id] = &elementIdStructure{ CommonId: a.Common.Id, Index: a.Index, @@ -77,7 +87,7 @@ func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStru } } // 初始化道岔信息 - for _, t := range graphicData.Turnouts { + for _, t := range data.Turnouts { gus.TurnoutIds[t.Common.Id] = &elementIdStructure{ CommonId: t.Common.Id, Index: t.Index, @@ -85,7 +95,7 @@ func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStru } } // 初始化物理区段信息 - for _, s := range graphicData.Section { + for _, s := range data.Section { gus.PhysicalSectionIds[s.Common.Id] = &elementIdStructure{ CommonId: s.Common.Id, Index: s.Index, @@ -93,7 +103,7 @@ func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStru } } // 初始化信号机信息 - for _, s := range graphicData.Signals { + for _, s := range data.Signals { gus.SignalIds[s.Common.Id] = &elementIdStructure{ CommonId: s.Common.Id, Index: s.Index, @@ -101,7 +111,7 @@ func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStru } } // 初始化应答器 - for _, t := range graphicData.Transponders { + for _, t := range data.Transponders { gus.TransponderIds[t.Common.Id] = &elementIdStructure{ CommonId: t.Common.Id, Index: t.Index, @@ -109,46 +119,125 @@ func initStationUid(graphicData *graphicData.RtssGraphicStorage) *stationUidStru } } // 初始化坡度 - for _, s := range graphicData.Slopes { + for _, s := range data.Slopes { gus.SlopeIds[s.Common.Id] = &elementIdStructure{ CommonId: s.Common.Id, Uid: GenerateElementUid(city, lineId, nil, s.Common.Id), } } // 初始化曲线 - for _, c := range graphicData.Curvatures { + for _, c := range data.Curvatures { gus.CurvatureIds[c.Common.Id] = &elementIdStructure{ CommonId: c.Common.Id, Uid: GenerateElementUid(city, lineId, nil, c.Common.Id), } } + //处理车站关联的组合信息 + refMap := make(map[string]*deviceRelateUidPriex) + for _, s := range data.StationRelateDeviceList { + for _, c := range s.Combinationtypes { + p := &deviceRelateUidPriex{deviceCode: s.Code, typeCode: c.Code} + for _, i := range c.RefDevices { + refMap[i] = p + } + } + } + // 初始化站场图按钮 + for _, b := range data.EsbButtons { + p := refMap[b.Common.Id] + code := b.Code + if p != nil { + code = p.deviceCode + "_" + p.typeCode + "_" + b.Code + } + gus.ButtonIds[b.Common.Id] = &elementIdStructure{ + CommonId: b.Common.Id, + Uid: GenerateElementUid(city, lineId, nil, code), + } + } + // 处理车站信息 + for _, s := range data.Stations { + gus.StationIds[s.Common.Id] = &elementIdStructure{ + CommonId: s.Common.Id, + Uid: GenerateElementUid(city, lineId, nil, s.Code), + } + // 处理关联的IBP盘信息 + if s.RefIbpMapCode == "" { + continue + } + ibpId, _ := strconv.Atoi(s.RefIbpMapCode) + ibpMapData, ok := giDataMap.Load(ibpId) + if !ok { + continue + } + initIBPUid(gus, city, lineId, s, ibpMapData.(*graphicData.IBPGraphicStorage)) + } return gus } -// 初始化继电器柜 UID -func initRelayCabinetUid(graphicData *graphicData.RelayCabinetGraphicStorage) *relayUidStructure { - rus := &relayUidStructure{ - RelayCabinetIds: make(map[string]*elementIdStructure, len(graphicData.RelayCabinets)), - RelayIds: make(map[string]*elementIdStructure, len(graphicData.Relays)), +// 处理IBP盘信息 +func initIBPUid(gus *stationUidStructure, city, lineId string, station *graphicData.Station, data *graphicData.IBPGraphicStorage) { + // 设备所属组合 + refMap := make(map[string]string) + for _, r := range data.IbpRelatedDevices { + for _, c := range r.Combinationtypes { + for _, i := range c.RefDevices { + refMap[i] = c.Code + } + } } - // 获取继电器的关联关系 - type relayUidPriex struct { - deviceCode string - typeCode string + getCode := func(id, code string) string { + p := refMap[id] + if p == "" { + return code + } + return p + "_" + code + } + for _, d := range data.IbpButtons { // ibp按钮 + gus.IBPIds[d.Common.Id] = &elementIdStructure{ + CommonId: d.Common.Id, + Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)), + } + } + for _, d := range data.IbpKeys { // ibp钥匙 + gus.IBPIds[d.Common.Id] = &elementIdStructure{ + CommonId: d.Common.Id, + Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)), + } + } + for _, d := range data.IbpAlarms { // ibp报警器 + gus.IBPIds[d.Common.Id] = &elementIdStructure{ + CommonId: d.Common.Id, + Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)), + } + } + for _, d := range data.IbpLights { // ibp指示灯 + gus.IBPIds[d.Common.Id] = &elementIdStructure{ + CommonId: d.Common.Id, + Uid: GenerateElementUid(city, lineId, []string{station.Code}, getCode(d.Common.Id, d.Code)), + } + } +} + +// 初始化继电器柜 UID +func initRelayCabinetUid(data *graphicData.RelayCabinetGraphicStorage) *relayUidStructure { + rus := &relayUidStructure{ + RelayCabinetIds: make(map[string]*elementIdStructure, len(data.RelayCabinets)), + RelayIds: make(map[string]*elementIdStructure, len(data.Relays)), } // 继电器所属设备 - refMap := make(map[string]*relayUidPriex, len(graphicData.Relays)) - for _, r := range graphicData.DeviceRelateRelayList { + refMap := make(map[string]*deviceRelateUidPriex, len(data.Relays)) + for _, r := range data.DeviceRelateRelayList { + isStation := r.DeviceType == graphicData.RelatedRef_station for _, c := range r.Combinationtypes { - p := &relayUidPriex{deviceCode: r.Code, typeCode: c.Code} + p := &deviceRelateUidPriex{deviceCode: r.Code, typeCode: c.Code, isStation: isStation} for _, i := range c.RefRelays { refMap[i] = p } } } // 获取公共前缀 - city, lineId, station := getUIdPrefix(graphicData.UniqueIdPrefix) - for _, r := range graphicData.RelayCabinets { + city, lineId, station := getUIdPrefix(data.UniqueIdPrefix) + for _, r := range data.RelayCabinets { rus.RelayCabinetIds[r.Common.Id] = &elementIdStructure{ CommonId: r.Common.Id, Code: r.Code, @@ -156,31 +245,38 @@ func initRelayCabinetUid(graphicData *graphicData.RelayCabinetGraphicStorage) *r } } // city+line+车站+设备code+继电器组合的code+继电器的code - for _, r := range graphicData.Relays { + for _, r := range data.Relays { p := refMap[r.Common.Id] code := r.Code if p != nil { code = p.deviceCode + "_" + p.typeCode + "_" + r.Code } + stationArr := []string{station} + if p != nil && p.isStation { + stationArr = nil + } rus.RelayIds[r.Common.Id] = &elementIdStructure{ CommonId: r.Common.Id, Code: r.Code, - Uid: GenerateElementUid(city, lineId, []string{station}, code), + Uid: GenerateElementUid(city, lineId, stationArr, code), } } - for _, r := range graphicData.PhaseFailureProtectors { + for _, r := range data.PhaseFailureProtectors { p := refMap[r.Common.Id] code := r.Code if p != nil { code = p.deviceCode + "_" + p.typeCode + "_" + r.Code } + stationArr := []string{station} + if p != nil && p.isStation { + stationArr = nil + } rus.RelayIds[r.Common.Id] = &elementIdStructure{ CommonId: r.Common.Id, Code: r.Code, - Uid: GenerateElementUid(city, lineId, []string{station}, code), + Uid: GenerateElementUid(city, lineId, stationArr, code), } } - return rus } @@ -208,6 +304,8 @@ func buildRepositoryAllUidsMap(mapIds []int32, repo *repository.Repository) map[ saveToAllUidMap(u.TurnoutIds) saveToAllUidMap(u.SlopeIds) saveToAllUidMap(u.CurvatureIds) + saveToAllUidMap(u.ButtonIds) + saveToAllUidMap(u.IBPIds) continue } } @@ -244,6 +342,11 @@ func getUidMapByType(uidData any, m interface{}) map[string]*elementIdStructure return (uidData.(*relayUidStructure)).RelayCabinetIds case *graphicData.Relay: return (uidData.(*relayUidStructure)).RelayIds + case *graphicData.EsbButton: + return (uidData.(*stationUidStructure)).ButtonIds + // Ibp相关 + case *graphicData.IBPButton, *graphicData.IbpAlarm, *graphicData.IbpKey, *graphicData.IbpLight: + return (uidData.(*stationUidStructure)).IBPIds default: panic(&dto.ErrorDto{Code: dto.ArgumentParseError, Message: "类型未映射字段"}) } diff --git a/ats/verify/simulation/wayside/memory/wayside_memory_signal.go b/ats/verify/simulation/wayside/memory/wayside_memory_signal.go index 50c9e7c..c20fbfa 100644 --- a/ats/verify/simulation/wayside/memory/wayside_memory_signal.go +++ b/ats/verify/simulation/wayside/memory/wayside_memory_signal.go @@ -1,36 +1,42 @@ package memory import ( + "fmt" + + "joylink.club/bj-rtsts-server/ats/verify/protos/graphicData" "joylink.club/bj-rtsts-server/ats/verify/protos/state" "joylink.club/ecs" + "joylink.club/rtsssimulation/consts" "joylink.club/rtsssimulation/fi" + "joylink.club/rtsssimulation/repository" + "joylink.club/rtsssimulation/repository/model/proto" ) -func ChangeSignalState(simulation *VerifySimulation, status *state.SignalState, mapId int32) { - // signalUid := QueryUidByMidAndComId(mapId, status.Id, &graphicData.Signal{}) - // signalModel, err := simulation.Repo.FindModel(signalUid, proto.DeviceType_DeviceType_Signal) - // if err != nil { - // panic(fmt.Sprintf("信号机[%s]模型不存在", signalUid)) - // } - // signalGroupCode := signalModel.(*repository.Signal).Code() - // switch signalGroupCode { - // case consts.SIGNAL_2XH1: - // changeSignal2XH1State(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_3XH1: - // changeSignal3XH1State(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_3XH2: - // changeSignal3XH2State(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_3XH3: - // changeSignal3XH3State(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_3XH4: - // changeSignal3XH4State(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_DCXH: - // changeSignalDCXHState(simulation.World, signalUid, status.GetAspect()) - // case consts.SIGNAL_JCKXH: - // changeSignalJCKXHState(simulation.World, signalUid, status.GetAspect()) - // default: - // panic(fmt.Sprintf("操作[%s]的信号机,无法识别组合类型[%s]", signalUid, signalGroupCode)) - // } +func ChangeSignalState(simulation *VerifySimulation, mapId int32, signalDeviceId string, toAspect state.Signal_Aspect) { + signalUid := QueryUidByMidAndComId(mapId, signalDeviceId, &graphicData.Signal{}) + signalModel, err := simulation.Repo.FindModel(signalUid, proto.DeviceType_DeviceType_Signal) + if err != nil { + panic(fmt.Sprintf("信号机[%s]模型不存在", signalUid)) + } + signalGroupCode := signalModel.(*repository.Signal).Code() + switch signalGroupCode { + case consts.SIGNAL_2XH1: + changeSignal2XH1State(simulation.World, signalUid, toAspect) + case consts.SIGNAL_3XH1: + changeSignal3XH1State(simulation.World, signalUid, toAspect) + case consts.SIGNAL_3XH2: + changeSignal3XH2State(simulation.World, signalUid, toAspect) + case consts.SIGNAL_3XH3: + changeSignal3XH3State(simulation.World, signalUid, toAspect) + case consts.SIGNAL_3XH4: + changeSignal3XH4State(simulation.World, signalUid, toAspect) + case consts.SIGNAL_DCXH: + changeSignalDCXHState(simulation.World, signalUid, toAspect) + case consts.SIGNAL_JCKXH: + changeSignalJCKXHState(simulation.World, signalUid, toAspect) + default: + panic(fmt.Sprintf("操作[%s]的信号机,无法识别组合类型[%s]", signalUid, signalGroupCode)) + } } func changeSignalJCKXHState(w ecs.World, signalUid string, toAspect state.Signal_Aspect) { switch toAspect {