【修改IBP设备UID逻辑】

This commit is contained in:
weizhihong 2023-12-07 10:17:48 +08:00
parent 74b86a9b12
commit 7545bd2ca6
7 changed files with 154 additions and 45 deletions

View File

@ -405,7 +405,7 @@ func ibpBtnOperation(c *gin.Context) {
} }
simulation := checkDeviceDataAndReturn(req.SimulationId) simulation := checkDeviceDataAndReturn(req.SimulationId)
slog.Info("传入状态参数", req) slog.Info("传入状态参数", req)
err := memory.ChangeIBPButtonState(simulation, req.MapId, req.StationId, req.ButtonCode, req.Down) err := memory.ChangeIBPButtonState(simulation, req.MapId, req.StationId, req.ButtonId, req.Down)
if err != nil { if err != nil {
panic(sys_error.New(fmt.Sprintf("IBP按钮操作失败,%s", err.Error()), err)) panic(sys_error.New(fmt.Sprintf("IBP按钮操作失败,%s", err.Error()), err))
} }
@ -435,7 +435,7 @@ func ibpKeyOperation(c *gin.Context) {
} }
simulation := checkDeviceDataAndReturn(req.SimulationId) simulation := checkDeviceDataAndReturn(req.SimulationId)
slog.Info("传入状态参数", req) slog.Info("传入状态参数", req)
err := memory.ChangeIBPKeyState(simulation, req.MapId, req.StationId, req.KeyCode, req.Gear) err := memory.ChangeIBPKeyState(simulation, req.MapId, req.StationId, req.KeyId, req.Gear)
if err != nil { if err != nil {
panic(sys_error.New(fmt.Sprintf("IBP开关操作失败,%s", err.Error()), err)) panic(sys_error.New(fmt.Sprintf("IBP开关操作失败,%s", err.Error()), err))
} }

View File

@ -119,7 +119,7 @@ type IBPButtonOperationReqDto struct {
SimulationId string `form:"simulationId" json:"simulationId" binding:"required"` SimulationId string `form:"simulationId" json:"simulationId" binding:"required"`
MapId int32 `json:"mapId" from:"mapId" binding:"required"` MapId int32 `json:"mapId" from:"mapId" binding:"required"`
StationId string `form:"stationId" json:"stationId" binding:"required"` StationId string `form:"stationId" json:"stationId" binding:"required"`
ButtonCode string `form:"buttonCode" json:"buttonCode" binding:"required"` ButtonId string `form:"buttonId" json:"buttonId" binding:"required"`
Down bool `form:"down" json:"down"` Down bool `form:"down" json:"down"`
} }
@ -135,7 +135,7 @@ type KeyOperationReqDto struct {
SimulationId string `form:"simulationId" json:"simulationId" binding:"required"` SimulationId string `form:"simulationId" json:"simulationId" binding:"required"`
MapId int32 `json:"mapId" from:"mapId" binding:"required"` MapId int32 `json:"mapId" from:"mapId" binding:"required"`
StationId string `form:"stationId" json:"stationId" binding:"required"` StationId string `form:"stationId" json:"stationId" binding:"required"`
KeyCode string `form:"keyCode" json:"keyCode"` KeyId string `form:"keyId" json:"keyId"`
Gear int32 `form:"gear" json:"gear"` Gear int32 `form:"gear" json:"gear"`
} }

View File

@ -60,20 +60,21 @@ func (ms *IbpMs) collectStationIbpState(station *graphicData.Station) (*state.Pu
return nil, nil return nil, nil
} }
stationUid := memory.QueryUidByMidAndComId(ms.mapId, station.Common.Id, &graphicData.Station{}) stationUid := memory.QueryUidByMidAndComId(ms.mapId, station.Common.Id, &graphicData.Station{})
ibpStorage := memory.GetStorageIBPMapData(station.RefIbpMapCode) ibpMapId, ibpStorage := memory.GetStorageIBPMapData(station.RefIbpMapCode)
buttonStates, err := ms.collectIBPButtonState(stationUid, ibpStorage.IbpButtons) ibpUidsMap := memory.QueryUidStructure[*memory.IBPUidStructure](ibpMapId)
buttonStates, err := ms.collectIBPButtonState(stationUid, ibpUidsMap, ibpStorage.IbpButtons)
if err != nil { if err != nil {
return nil, err return nil, err
} }
alarmStates, err := ms.collectIBPAlarmState(stationUid, ibpStorage.IbpAlarms) alarmStates, err := ms.collectIBPAlarmState(stationUid, ibpUidsMap, ibpStorage.IbpAlarms)
if err != nil { if err != nil {
return nil, err return nil, err
} }
lightStates, err := ms.collectIBPLightState(stationUid, ibpStorage.IbpLights) lightStates, err := ms.collectIBPLightState(stationUid, ibpUidsMap, ibpStorage.IbpLights)
if err != nil { if err != nil {
return nil, err return nil, err
} }
keyStates, err := ms.collectIBPKeyState(stationUid, ibpStorage.IbpKeys) keyStates, err := ms.collectIBPKeyState(stationUid, ibpUidsMap, ibpStorage.IbpKeys)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -89,12 +90,13 @@ func (ms *IbpMs) collectStationIbpState(station *graphicData.Station) (*state.Pu
} }
// 收集IBP按钮状态 // 收集IBP按钮状态
func (ms *IbpMs) collectIBPButtonState(stationUid string, ibpButtons []*graphicData.IBPButton) ([]*state.ButtonState, error) { func (ms *IbpMs) collectIBPButtonState(stationUid string, uidsMap *memory.IBPUidStructure, ibpButtons []*graphicData.IBPButton) ([]*state.ButtonState, error) {
var states []*state.ButtonState var states []*state.ButtonState
for _, data := range ibpButtons { // 按钮 for _, data := range ibpButtons { // 按钮
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_button_"+data.Code) uid := stationUid + "_" + uidsMap.IbpButtonIds[data.Common.Id].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok { if !ok {
return nil, fmt.Errorf("ibp按钮实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_button_"+data.Code) return nil, fmt.Errorf("ibp按钮实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), uid)
} }
if entry.HasComponent(component.ButtonTag) { if entry.HasComponent(component.ButtonTag) {
states = append(states, getIBPButtonState(data.Common.Id, entry)) states = append(states, getIBPButtonState(data.Common.Id, entry))
@ -117,12 +119,13 @@ func getIBPButtonState(id string, entry *ecs.Entry) *state.ButtonState {
} }
// 收集报警器状态 // 收集报警器状态
func (ms *IbpMs) collectIBPAlarmState(stationUid string, ibpAlarms []*graphicData.IbpAlarm) ([]*state.AlarmState, error) { func (ms *IbpMs) collectIBPAlarmState(stationUid string, uidsMap *memory.IBPUidStructure, ibpAlarms []*graphicData.IbpAlarm) ([]*state.AlarmState, error) {
var states []*state.AlarmState var states []*state.AlarmState
for _, data := range ibpAlarms { // 报警器 for _, data := range ibpAlarms { // 报警器
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_alarm_"+data.Code) uid := stationUid + "_" + uidsMap.IbpAlarmIds[data.Common.Id].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok { if !ok {
return nil, fmt.Errorf("ibp报警器实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_alarm_"+data.Code) return nil, fmt.Errorf("ibp报警器实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), uid)
} }
if entry.HasComponent(component.AlarmTag) { if entry.HasComponent(component.AlarmTag) {
states = append(states, &state.AlarmState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val}) states = append(states, &state.AlarmState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val})
@ -132,12 +135,13 @@ func (ms *IbpMs) collectIBPAlarmState(stationUid string, ibpAlarms []*graphicDat
} }
// 收集灯状态信息 // 收集灯状态信息
func (ms *IbpMs) collectIBPLightState(stationUid string, ibpLights []*graphicData.IbpLight) ([]*state.LightState, error) { func (ms *IbpMs) collectIBPLightState(stationUid string, uidsMap *memory.IBPUidStructure, ibpLights []*graphicData.IbpLight) ([]*state.LightState, error) {
var states []*state.LightState var states []*state.LightState
for _, data := range ibpLights { // 指示灯 for _, data := range ibpLights { // 指示灯
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_light_"+data.Code) uid := stationUid + "_" + uidsMap.IbpLightIds[data.Common.Id].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok { if !ok {
return nil, fmt.Errorf("ibp指示灯实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_light_"+data.Code) return nil, fmt.Errorf("ibp指示灯实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), uid)
} }
if entry.HasComponent(component.LightTag) { if entry.HasComponent(component.LightTag) {
states = append(states, &state.LightState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val}) states = append(states, &state.LightState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val})
@ -147,12 +151,13 @@ func (ms *IbpMs) collectIBPLightState(stationUid string, ibpLights []*graphicDat
} }
// 收集钥匙状态 // 收集钥匙状态
func (ms *IbpMs) collectIBPKeyState(stationUid string, ibpKeys []*graphicData.IbpKey) ([]*state.KeyState, error) { func (ms *IbpMs) collectIBPKeyState(stationUid string, uidsMap *memory.IBPUidStructure, ibpKeys []*graphicData.IbpKey) ([]*state.KeyState, error) {
var states []*state.KeyState var states []*state.KeyState
for _, data := range ibpKeys { // 钥匙 for _, data := range ibpKeys { // 钥匙
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_key_"+data.Code) uid := stationUid + "_" + uidsMap.IbpKeyIds[data.Common.Id].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok { if !ok {
return nil, fmt.Errorf("ibp钥匙实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_key_"+data.Code) return nil, fmt.Errorf("ibp钥匙实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), uid)
} }
if entry.HasComponent(component.KeyTag) { if entry.HasComponent(component.KeyTag) {
states = append(states, &state.KeyState{Id: data.Common.Id, Gear: component.GearStateType.Get(entry).Val}) states = append(states, &state.KeyState{Id: data.Common.Id, Gear: component.GearStateType.Get(entry).Val})

View File

@ -1,22 +1,58 @@
package memory package memory
import ( import (
"fmt"
"joylink.club/bj-rtsts-server/ts/protos/graphicData" "joylink.club/bj-rtsts-server/ts/protos/graphicData"
"joylink.club/rtsssimulation/fi" "joylink.club/rtsssimulation/fi"
) )
// 操作IBP按钮 // 操作IBP按钮
func ChangeIBPButtonState(sim *VerifySimulation, mapId int32, stationId, btnCode string, pressDown bool) error { func ChangeIBPButtonState(sim *VerifySimulation, mapId int32, stationId, btnId string, pressDown bool) error {
uidMap, err := getIbpUidByMapIdAndStationId(mapId, stationId)
if err != nil {
return err
}
if uidMap.IbpButtonIds[btnId] == nil {
return fmt.Errorf("车站【%s】按钮【%s】UID不存在", stationId, btnId)
}
stationUid := QueryUidByMidAndComId(mapId, stationId, &graphicData.Station{}) stationUid := QueryUidByMidAndComId(mapId, stationId, &graphicData.Station{})
if pressDown { if pressDown {
return fi.PressDownButton(sim.World, stationUid+"_button_"+btnCode) return fi.PressDownButton(sim.World, stationUid+"_"+uidMap.IbpButtonIds[btnId].Uid)
} else { } else {
return fi.PressUpButton(sim.World, stationUid+"_button_"+btnCode) return fi.PressUpButton(sim.World, stationUid+"_"+uidMap.IbpButtonIds[btnId].Uid)
} }
} }
// 操作IBP按钮 // 操作IBP按钮
func ChangeIBPKeyState(sim *VerifySimulation, mapId int32, stationId, keyCode string, gear int32) error { func ChangeIBPKeyState(sim *VerifySimulation, mapId int32, stationId, keyId string, gear int32) error {
uidMap, err := getIbpUidByMapIdAndStationId(mapId, stationId)
if err != nil {
return err
}
if uidMap.IbpKeyIds[keyId] == nil {
return fmt.Errorf("车站【%s】钥匙【%s】UID不存在", stationId, keyId)
}
stationUid := QueryUidByMidAndComId(mapId, stationId, &graphicData.Station{}) stationUid := QueryUidByMidAndComId(mapId, stationId, &graphicData.Station{})
return fi.SwitchKeyGear(sim.World, stationUid+"_key_"+keyCode, gear) return fi.SwitchKeyGear(sim.World, stationUid+"_"+uidMap.IbpKeyIds[keyId].Uid, gear)
}
// 根据平面布置图ID、列车ID获取IbpUid信息
func getIbpUidByMapIdAndStationId(mapId int32, stationId string) (*IBPUidStructure, error) {
giData := QueryGiData[*graphicData.RtssGraphicStorage](mapId)
var station *graphicData.Station
for _, s := range giData.Stations {
if s.Common.Id == stationId {
station = s
break
}
}
if station == nil {
return nil, fmt.Errorf("地图【%d】车站【%s】不存在", mapId, stationId)
}
if station.RefIbpMapCode == "" {
return nil, fmt.Errorf("车站【%s】未关联IBP地图", station.StationName)
}
return QueryUidStructure[*IBPUidStructure](QueryGiId(station.RefIbpMapCode)), nil
} }

View File

@ -54,6 +54,9 @@ func PublishMapVerifyStructure(graphic *dto.PublishedDto) {
case graphicData.PictureType_RelayCabinetLayout: case graphicData.PictureType_RelayCabinetLayout:
graphicStorage := message.(*graphicData.RelayCabinetGraphicStorage) graphicStorage := message.(*graphicData.RelayCabinetGraphicStorage)
giUidMap.Store(graphic.ID, initRelayCabinetUid(graphicStorage)) giUidMap.Store(graphic.ID, initRelayCabinetUid(graphicStorage))
case graphicData.PictureType_IBP:
graphicStorage := message.(*graphicData.IBPGraphicStorage)
giUidMap.Store(graphic.ID, initIBPUid(graphicStorage))
} }
} }
@ -105,20 +108,20 @@ func QueryGiId(name string) int32 {
return value.(int32) return value.(int32)
} }
func GetStorageIBPMapData(mapCode string) *graphicData.IBPGraphicStorage { func GetStorageIBPMapData(mapCode string) (int32, *graphicData.IBPGraphicStorage) {
// 处理关联的IBP盘信息 // 处理关联的IBP盘信息
if mapCode == "" { if mapCode == "" {
return nil return 0, nil
} }
ibpId, ok := giNameMap.Load(mapCode) ibpId, ok := giNameMap.Load(mapCode)
if !ok { if !ok {
return nil return 0, nil
} }
ibpMapData, ok := giDataMap.Load(ibpId) ibpMapData, ok := giDataMap.Load(ibpId)
if !ok { if !ok {
return nil return ibpId.(int32), nil
} }
return ibpMapData.(*graphicData.IBPGraphicStorage) return ibpId.(int32), ibpMapData.(*graphicData.IBPGraphicStorage)
} }
// 转换成统一坐标公里标 // 转换成统一坐标公里标

View File

@ -40,6 +40,13 @@ type RelayUidStructure struct {
RelayIds map[string]*elementIdStructure RelayIds map[string]*elementIdStructure
} }
type IBPUidStructure struct {
IbpButtonIds map[string]*elementIdStructure
IbpAlarmIds map[string]*elementIdStructure
IbpKeyIds map[string]*elementIdStructure
IbpLightIds map[string]*elementIdStructure
}
// 获取继电器的关联关系 // 获取继电器的关联关系
type deviceRelateUidPriex struct { type deviceRelateUidPriex struct {
deviceCode string deviceCode string
@ -481,6 +488,65 @@ func initRelayCabinetUid(data *graphicData.RelayCabinetGraphicStorage) *RelayUid
return rus return rus
} }
// 初始化IBP地图UID
func initIBPUid(data *graphicData.IBPGraphicStorage) *IBPUidStructure {
rus := &IBPUidStructure{
IbpButtonIds: make(map[string]*elementIdStructure),
IbpAlarmIds: make(map[string]*elementIdStructure),
IbpKeyIds: make(map[string]*elementIdStructure),
IbpLightIds: make(map[string]*elementIdStructure),
}
//处理继电器关联信息
refMap := make(map[string]string)
for _, s := range data.IbpRelatedDevices {
for _, c := range s.Combinationtypes {
for _, i := range c.RefDevices {
refMap[i] = c.Code
}
}
}
codeFun := func(id, code string) string {
if refMap[id] != "" {
return refMap[id] + "_" + code
} else {
return code
}
}
// 处理按钮Uid
for _, d := range data.IbpButtons {
rus.IbpButtonIds[d.Common.Id] = &elementIdStructure{
CommonId: d.Common.Id,
Code: d.Code,
Uid: "button_" + codeFun(d.Common.Id, d.Code),
}
}
// 处理钥匙Uid
for _, d := range data.IbpKeys {
rus.IbpKeyIds[d.Common.Id] = &elementIdStructure{
CommonId: d.Common.Id,
Code: d.Code,
Uid: "key_" + codeFun(d.Common.Id, d.Code),
}
}
// 处理报警器Uid
for _, d := range data.IbpAlarms {
rus.IbpAlarmIds[d.Common.Id] = &elementIdStructure{
CommonId: d.Common.Id,
Code: d.Code,
Uid: "alarm_" + codeFun(d.Common.Id, d.Code),
}
}
// 处理指示灯Uid
for _, d := range data.IbpLights {
rus.IbpLightIds[d.Common.Id] = &elementIdStructure{
CommonId: d.Common.Id,
Code: d.Code,
Uid: "light_" + codeFun(d.Common.Id, d.Code),
}
}
return rus
}
// 构建仿真内所有地图UID映射信号布置图ID,这里为了解决多地图时根据UID反向寻找避免多次循环地图直接获取平面布置图元素 // 构建仿真内所有地图UID映射信号布置图ID,这里为了解决多地图时根据UID反向寻找避免多次循环地图直接获取平面布置图元素
func buildRepositoryAllUidsMap(mapIds []int32, repo *repository.Repository) map[string]*elementIdStructure { func buildRepositoryAllUidsMap(mapIds []int32, repo *repository.Repository) map[string]*elementIdStructure {
mapLen := len(repo.CheckPointList()) + len(repo.PhysicalSectionList()) + len(repo.SignalList()) + mapLen := len(repo.CheckPointList()) + len(repo.PhysicalSectionList()) + len(repo.SignalList()) +
@ -514,7 +580,7 @@ func buildRepositoryAllUidsMap(mapIds []int32, repo *repository.Repository) map[
} }
// 获取地图UID的映射集合 // 获取地图UID的映射集合
func QueryUidStructure[T *StationUidStructure | *RelayUidStructure](mapId int32) T { func QueryUidStructure[T *StationUidStructure | *RelayUidStructure | *IBPUidStructure](mapId int32) T {
uidData, ok := giUidMap.Load(mapId) uidData, ok := giUidMap.Load(mapId)
if !ok { if !ok {
panic(fmt.Errorf("id=%d的发布图没有uid缓存数据", mapId)) panic(fmt.Errorf("id=%d的发布图没有uid缓存数据", mapId))

View File

@ -1126,7 +1126,7 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
Code: data.StationName, Code: data.StationName,
} }
// 关联车站的设备 // 关联车站的设备
refs, ok := relateMap[data.Code] refs, ok := relateMap[station.Code]
if ok { if ok {
for _, c := range refs.Combinationtypes { for _, c := range refs.Combinationtypes {
group := &proto.ElectronicGroup{Code: c.Code} group := &proto.ElectronicGroup{Code: c.Code}
@ -1214,23 +1214,23 @@ func fillProtoRepository(repo *proto.Repository, storage *graphicData.RtssGraphi
} }
// 将IBP的设备关联到车站中 // 将IBP的设备关联到车站中
func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, ibpMap string) { func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, ibpMapCode string) {
storage := GetStorageIBPMapData(ibpMap) mapId, storage := GetStorageIBPMapData(ibpMapCode)
if storage == nil { if storage == nil {
return return
} }
uidMap := QueryUidStructure[*IBPUidStructure](mapId)
deviceMap := make(map[string]*proto.ElectronicComponent) // 对应的设备类型 deviceMap := make(map[string]*proto.ElectronicComponent) // 对应的设备类型
for _, data := range storage.IbpButtons { // 处理按钮 for _, data := range storage.IbpButtons { // 处理按钮
buttonType := proto.Button_NO_Reset_Press
if data.IsSelfReset {
buttonType = proto.Button_Reset_Press
}
b := &proto.Button{ b := &proto.Button{
Id: station.Id + "_button_" + data.Code, Id: station.Id + "_" + uidMap.IbpButtonIds[data.Common.Id].Uid,
Code: data.Code, Code: data.Code,
ButtonType: buttonType, ButtonType: proto.Button_NO_Reset_Press,
HasLight: data.HasLight, HasLight: data.HasLight,
} }
if data.IsSelfReset {
b.ButtonType = proto.Button_Reset_Press
}
deviceMap[data.Common.Id] = &proto.ElectronicComponent{ deviceMap[data.Common.Id] = &proto.ElectronicComponent{
Id: b.Id, Id: b.Id,
DeviceType: proto.DeviceType_DeviceType_Button, DeviceType: proto.DeviceType_DeviceType_Button,
@ -1239,7 +1239,7 @@ func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, i
} }
for _, data := range storage.IbpKeys { // 钥匙 for _, data := range storage.IbpKeys { // 钥匙
b := &proto.Key{ b := &proto.Key{
Id: station.Id + "_key_" + data.Code, Id: station.Id + "_" + uidMap.IbpKeyIds[data.Common.Id].Uid,
Code: data.Code, Code: data.Code,
Gear: 2, Gear: 2,
} }
@ -1251,7 +1251,7 @@ func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, i
} }
for _, data := range storage.IbpAlarms { // 报警器 for _, data := range storage.IbpAlarms { // 报警器
b := &proto.Alarm{ b := &proto.Alarm{
Id: station.Id + "_alarm_" + data.Code, Id: station.Id + "_" + uidMap.IbpAlarmIds[data.Common.Id].Uid,
Code: data.Code, Code: data.Code,
} }
deviceMap[data.Common.Id] = &proto.ElectronicComponent{ deviceMap[data.Common.Id] = &proto.ElectronicComponent{
@ -1262,10 +1262,9 @@ func handlerIBPDeviceToStation(station *proto.Station, repo *proto.Repository, i
} }
for _, data := range storage.IbpLights { // 指示灯, for _, data := range storage.IbpLights { // 指示灯,
b := &proto.Light{ b := &proto.Light{
Id: station.Id + "_light_" + data.Code, Id: station.Id + "_" + uidMap.IbpLightIds[data.Common.Id].Uid,
Code: data.Code, Code: data.Code,
} }
// 存入组合类型的
deviceMap[data.Common.Id] = &proto.ElectronicComponent{ deviceMap[data.Common.Id] = &proto.ElectronicComponent{
Id: b.Id, Id: b.Id,
DeviceType: proto.DeviceType_DeviceType_Light, DeviceType: proto.DeviceType_DeviceType_Light,