rts-sim-testing-service/message_server/ibp_ms.go
2023-12-14 13:04:48 +08:00

179 lines
5.6 KiB
Go

package message_server
import (
"fmt"
"time"
"google.golang.org/protobuf/proto"
"joylink.club/bj-rtsts-server/message_server/ms_api"
"joylink.club/bj-rtsts-server/ts/protos/graphicData"
"joylink.club/bj-rtsts-server/ts/protos/state"
"joylink.club/bj-rtsts-server/ts/simulation/wayside/memory"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"joylink.club/rtsssimulation/entity"
)
// 综合后备盘IBP消息服务
type IbpMs struct {
vs *memory.VerifySimulation
mapId int32
}
func NewIBPMs(vs *memory.VerifySimulation, mapId int32) *IbpMs {
return &IbpMs{vs: vs, mapId: mapId}
}
func (ms *IbpMs) GetChannel() string {
return SimulationIbpTopic
// return "simulation-ibp-%s_%d_%s-status"
}
func (ms *IbpMs) GetInterval() time.Duration {
return 200 * time.Millisecond
}
func (ms *IbpMs) OnTick() ([]*ms_api.TopicMsg, error) {
var msgArr []*ms_api.TopicMsg
mapData := memory.QueryGiData[*graphicData.RtssGraphicStorage](ms.mapId)
for _, station := range mapData.Stations {
sid := memory.GetMapElementId(station.Common)
channel := ms.handlerIBPChannelName(sid)
stationIbpState, err := ms.collectStationIbpState(station)
if err != nil {
return nil, err
}
b, err := proto.Marshal(stationIbpState)
if err != nil {
return nil, fmt.Errorf("IBP设备状态消息服务数据序列化失败: %s", err)
}
msgArr = append(msgArr, ms_api.NewTopicMsg(channel, b))
}
return msgArr, nil
}
// 当发生错误时执行的逻辑
func (ms *IbpMs) OnError(err error) {
}
func (ms *IbpMs) collectStationIbpState(station *graphicData.Station) (*state.PushedDevicesStatus, error) {
if station.RefIbpMapCode == "" {
return nil, nil
}
sid := memory.GetMapElementId(station.Common)
stationUid := memory.QueryUidByMidAndComId(ms.mapId, sid, &graphicData.Station{})
ibpMapId, ibpStorage := memory.GetStorageIBPMapData(station.RefIbpMapCode)
ibpUidsMap := memory.QueryUidStructure[*memory.IBPUidStructure](ibpMapId)
buttonStates, err := ms.collectIBPButtonState(stationUid, ibpUidsMap, ibpStorage.IbpButtons)
if err != nil {
return nil, err
}
alarmStates, err := ms.collectIBPAlarmState(stationUid, ibpUidsMap, ibpStorage.IbpAlarms)
if err != nil {
return nil, err
}
lightStates, err := ms.collectIBPLightState(stationUid, ibpUidsMap, ibpStorage.IbpLights)
if err != nil {
return nil, err
}
keyStates, err := ms.collectIBPKeyState(stationUid, ibpUidsMap, ibpStorage.IbpKeys)
if err != nil {
return nil, err
}
return &state.PushedDevicesStatus{
All: true,
AllStatus: &state.AllDevicesStatus{
ButtonState: buttonStates,
AlarmState: alarmStates,
LightState: lightStates,
KeyState: keyStates,
},
}, nil
}
// 收集IBP按钮状态
func (ms *IbpMs) collectIBPButtonState(stationUid string, uidsMap *memory.IBPUidStructure, ibpButtons []*graphicData.IBPButton) ([]*state.ButtonState, error) {
var states []*state.ButtonState
for _, data := range ibpButtons { // 按钮
did := memory.GetMapElementId(data.Common)
uid := stationUid + "_" + uidsMap.IbpButtonIds[did].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok {
continue
}
if entry.HasComponent(component.ButtonTag) {
states = append(states, getIBPButtonState(did, entry))
}
}
return states, nil
}
// 获取IBP盘按钮状态
func getIBPButtonState(id uint32, entry *ecs.Entry) *state.ButtonState {
status := &state.ButtonState{Id: id}
bit := component.BitStateType.Get(entry)
status.Down = bit.Val
// 如果按钮包含灯
if entry.HasComponent(component.SingleLightType) {
lightComponent := component.SingleLightType.Get(entry)
status.Active = component.BitStateType.Get(lightComponent.Light).Val
}
return status
}
// 收集报警器状态
func (ms *IbpMs) collectIBPAlarmState(stationUid string, uidsMap *memory.IBPUidStructure, ibpAlarms []*graphicData.IbpAlarm) ([]*state.AlarmState, error) {
var states []*state.AlarmState
for _, data := range ibpAlarms { // 报警器
did := memory.GetMapElementId(data.Common)
uid := stationUid + "_" + uidsMap.IbpAlarmIds[did].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok {
continue
}
if entry.HasComponent(component.AlarmTag) {
states = append(states, &state.AlarmState{Id: did, Active: component.BitStateType.Get(entry).Val})
}
}
return states, nil
}
// 收集灯状态信息
func (ms *IbpMs) collectIBPLightState(stationUid string, uidsMap *memory.IBPUidStructure, ibpLights []*graphicData.IbpLight) ([]*state.LightState, error) {
var states []*state.LightState
for _, data := range ibpLights { // 指示灯
did := memory.GetMapElementId(data.Common)
uid := stationUid + "_" + uidsMap.IbpLightIds[did].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok {
continue
}
if entry.HasComponent(component.LightTag) {
states = append(states, &state.LightState{Id: did, Active: component.BitStateType.Get(entry).Val})
}
}
return states, nil
}
// 收集钥匙状态
func (ms *IbpMs) collectIBPKeyState(stationUid string, uidsMap *memory.IBPUidStructure, ibpKeys []*graphicData.IbpKey) ([]*state.KeyState, error) {
var states []*state.KeyState
for _, data := range ibpKeys { // 钥匙
did := memory.GetMapElementId(data.Common)
uid := stationUid + "_" + uidsMap.IbpKeyIds[did].Uid
entry, ok := entity.GetEntityByUid(ms.vs.World, uid)
if !ok {
continue
}
if entry.HasComponent(component.KeyTag) {
states = append(states, &state.KeyState{Id: did, Gear: component.GearStateType.Get(entry).Val})
}
}
return states, nil
}
// 处理订阅通道名称
func (ms *IbpMs) handlerIBPChannelName(stationId uint32) string {
return fmt.Sprintf(SimulationIbpTopic, ms.vs.SimulationId, ms.mapId, stationId)
}