169 lines
5.5 KiB
Go
169 lines
5.5 KiB
Go
package message_server
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
"joylink.club/bj-rtsts-server/config"
|
|
"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 SimulationDeviceStatesTopicPrefix + "/ibp/%s"
|
|
// 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 {
|
|
channel := ms.handlerIBPChannelName(station.Common.Id)
|
|
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
|
|
}
|
|
stationUid := memory.QueryUidByMidAndComId(ms.mapId, station.Common.Id, &graphicData.Station{})
|
|
ibpStorage := memory.GetStorageIBPMapData(station.RefIbpMapCode)
|
|
buttonStates, err := ms.collectIBPButtonState(stationUid, ibpStorage.IbpButtons)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
alarmStates, err := ms.collectIBPAlarmState(stationUid, ibpStorage.IbpAlarms)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
lightStates, err := ms.collectIBPLightState(stationUid, ibpStorage.IbpLights)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
keyStates, err := ms.collectIBPKeyState(stationUid, 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, ibpButtons []*graphicData.IBPButton) ([]*state.ButtonState, error) {
|
|
var states []*state.ButtonState
|
|
for _, data := range ibpButtons { // 按钮
|
|
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_button_"+data.Code)
|
|
if !ok {
|
|
return nil, fmt.Errorf("ibp按钮实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_button_"+data.Code)
|
|
}
|
|
if entry.HasComponent(component.ButtonTag) {
|
|
states = append(states, getIBPButtonState(data.Common.Id, entry))
|
|
}
|
|
}
|
|
return states, nil
|
|
}
|
|
|
|
// 获取IBP盘按钮状态
|
|
func getIBPButtonState(id string, 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, ibpAlarms []*graphicData.IbpAlarm) ([]*state.AlarmState, error) {
|
|
var states []*state.AlarmState
|
|
for _, data := range ibpAlarms { // 报警器
|
|
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_alarm_"+data.Code)
|
|
if !ok {
|
|
return nil, fmt.Errorf("ibp报警器实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_alarm_"+data.Code)
|
|
}
|
|
if entry.HasComponent(component.AlarmTag) {
|
|
states = append(states, &state.AlarmState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val})
|
|
}
|
|
}
|
|
return states, nil
|
|
}
|
|
|
|
// 收集灯状态信息
|
|
func (ms *IbpMs) collectIBPLightState(stationUid string, ibpLights []*graphicData.IbpLight) ([]*state.LightState, error) {
|
|
var states []*state.LightState
|
|
for _, data := range ibpLights { // 指示灯
|
|
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_light_"+data.Code)
|
|
if !ok {
|
|
return nil, fmt.Errorf("ibp指示灯实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_light_"+data.Code)
|
|
}
|
|
if entry.HasComponent(component.LightTag) {
|
|
states = append(states, &state.LightState{Id: data.Common.Id, Active: component.BitStateType.Get(entry).Val})
|
|
}
|
|
}
|
|
return states, nil
|
|
}
|
|
|
|
// 收集钥匙状态
|
|
func (ms *IbpMs) collectIBPKeyState(stationUid string, ibpKeys []*graphicData.IbpKey) ([]*state.KeyState, error) {
|
|
var states []*state.KeyState
|
|
for _, data := range ibpKeys { // 钥匙
|
|
entry, ok := entity.GetEntityByUid(ms.vs.World, stationUid+"_key_"+data.Code)
|
|
if !ok {
|
|
return nil, fmt.Errorf("ibp钥匙实体不存在: World id=%d, uid=%s", ms.vs.World.Id(), stationUid+"_key_"+data.Code)
|
|
}
|
|
if entry.HasComponent(component.KeyTag) {
|
|
states = append(states, &state.KeyState{Id: data.Common.Id, Gear: component.GearStateType.Get(entry).Val})
|
|
}
|
|
}
|
|
return states, nil
|
|
}
|
|
|
|
// 处理订阅通道名称
|
|
func (ms *IbpMs) handlerIBPChannelName(stationId string) string {
|
|
return fmt.Sprintf(ms.GetChannel(), config.SystemName, ms.vs.SimulationId, ms.mapId, stationId)
|
|
}
|