package repository import ( "fmt" "joylink.club/rtsssimulation/repository/model/proto" ) type Turnout struct { Identity // 岔心的公里标 km *proto.Kilometer switchMachineType proto.Turnout_SwitchMachineType // 道岔关联的道岔物理区段 section *PhysicalSection // A/B/C端口关联的设备端口(区段/道岔) aDevicePort DevicePort bDevicePort DevicePort cDevicePort DevicePort // A/B/C端口关联的Link端口 aLinkPort *LinkPort bLinkPort *LinkPort cLinkPort *LinkPort // A/B/C端口的边界的公里标 aKm *proto.Kilometer bKm *proto.Kilometer cKm *proto.Kilometer // A/B/C端口的边界在Link上的位置 aLinkPosition *LinkPosition bLinkPosition *LinkPosition cLinkPosition *LinkPosition // A/B/C方向关联的设备(目前有信号机、应答器、(非区段边界)检测点) aDevices []Identity bDevices []Identity cDevices []Identity componentGroups []*ElectronicComponentGroup } func NewTurnout(id string, km *proto.Kilometer, switchMachineType proto.Turnout_SwitchMachineType) *Turnout { return &Turnout{ Identity: identity{id, proto.DeviceType_DeviceType_Turnout}, km: km, switchMachineType: switchMachineType, } } // FindCircuitRoleById 根据继电器id获取在具体电路中的电路角色 // relayId-继电器id // relayGroup-继电器组合类型 // relayName-继电器在电路中的名称 // find-true找到,false未找到 func (t *Turnout) FindCircuitRoleById(relayId string) (relayGroup string, relayName string, find bool) { if t.componentGroups != nil { for _, rg := range t.componentGroups { for _, component := range rg.components { if relayId == component.Id() { switch component.Type() { case proto.DeviceType_DeviceType_Relay: return rg.code, component.(*Relay).code, true case proto.DeviceType_DeviceType_PhaseFailureProtector: return rg.code, component.(*PhaseFailureProtector).code, true } } } } } return "", "", false } // FindRelayModelByCRole 根据继电器具体电路角色来获取继电器设备模型 // relayGroup-继电器组合类型 // relayName-继电器在电路中的名称 func (t *Turnout) FindRelayModelByCRole(relayGroup string, relayName string) Identity { if t.componentGroups != nil { for _, rg := range t.componentGroups { for _, component := range rg.components { switch component.Type() { case proto.DeviceType_DeviceType_Relay: if rg.code == relayGroup && component.(*Relay).code == relayName { return component } case proto.DeviceType_DeviceType_PhaseFailureProtector: if rg.code == relayGroup && component.(*PhaseFailureProtector).code == relayName { return component } } } } } return nil } func (t *Turnout) PortNum() int { return 3 } func (t *Turnout) bindPhysicalSection(section *PhysicalSection) { t.section = section } func (t *Turnout) bindDevicePort(port proto.Port, devicePort DevicePort) error { _, isSectionPort := devicePort.(*PhysicalSectionPort) _, isTurnoutPort := devicePort.(*TurnoutPort) if !isSectionPort && !isTurnoutPort { return fmt.Errorf("道岔不能与[%s]类型的设备端口关联", devicePort.Device().Type()) } switch port { case proto.Port_A: t.aDevicePort = devicePort case proto.Port_B: t.bDevicePort = devicePort case proto.Port_C: t.cDevicePort = devicePort default: return fmt.Errorf("道岔无端口[%s]", port) } return nil } func (t *Turnout) bindLinkPort(port proto.Port, linkPort *LinkPort) { switch port { case proto.Port_A: t.aLinkPort = linkPort case proto.Port_B: t.bLinkPort = linkPort case proto.Port_C: t.cLinkPort = linkPort } } func (t *Turnout) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error { if km == nil || (km.CoordinateSystem == "" && km.Value == 0) { return nil } switch port { case proto.Port_A: t.aKm = km case proto.Port_B: t.bKm = km case proto.Port_C: t.cKm = km default: return fmt.Errorf("道岔无端口[%s]", port) } return nil } func (t *Turnout) bindLinkPosition(port proto.Port, position *LinkPosition) { switch port { case proto.Port_A: t.aLinkPosition = position case proto.Port_B: t.bLinkPosition = position case proto.Port_C: t.cLinkPosition = position } } func (t *Turnout) bindDevice(device Identity, port proto.Port) { switch port { case proto.Port_A: t.aDevices = append(t.aDevices, device) case proto.Port_B: t.bDevices = append(t.bDevices, device) case proto.Port_C: t.cDevices = append(t.cDevices, device) } } func (t *Turnout) checkPoints() []*CheckPoint { var cps []*CheckPoint for _, device := range t.aDevices { cp, ok := device.(*CheckPoint) if ok { cps = append(cps, cp) } } for _, device := range t.bDevices { cp, ok := device.(*CheckPoint) if ok { cps = append(cps, cp) } } for _, device := range t.cDevices { cp, ok := device.(*CheckPoint) if ok { cps = append(cps, cp) } } return cps } // 获取指定端口连接的设备端口 func (t *Turnout) findDevicePortByPort(port proto.Port) DevicePort { switch port { case proto.Port_A: return t.aDevicePort case proto.Port_B: return t.bDevicePort case proto.Port_C: return t.cDevicePort default: return nil } } func (t *Turnout) findBoundaryKmByPort(port proto.Port) *proto.Kilometer { switch port { case proto.Port_A: return t.aKm case proto.Port_B: return t.bKm case proto.Port_C: return t.cKm } return nil } func (t *Turnout) findDevicesByPort(port proto.Port) []Identity { switch port { case proto.Port_A: return t.aDevices case proto.Port_B: return t.bDevices case proto.Port_C: return t.cDevices } return nil } func (t *Turnout) FindLinkPositionByPort(port proto.Port) *LinkPosition { switch port { case proto.Port_A: return t.aLinkPosition case proto.Port_B: return t.bLinkPosition case proto.Port_C: return t.cLinkPosition } return nil } func (t *Turnout) FindLinkByPort(port proto.Port) *LinkPort { switch port { case proto.Port_A: return t.aLinkPort case proto.Port_B: return t.bLinkPort case proto.Port_C: return t.cLinkPort } return nil } func (t *Turnout) SwitchMachineType() proto.Turnout_SwitchMachineType { return t.switchMachineType } func (t *Turnout) GetTurnoutKm(port proto.Port) *proto.Kilometer { switch port { case proto.Port_A: return t.aKm case proto.Port_B: return t.bKm case proto.Port_C: return t.cKm } return t.km } func (t *Turnout) RelayGroups() []*ElectronicComponentGroup { return t.componentGroups } func (t *Turnout) FindRelay(groupCode, relayCode string) *Relay { for _, group := range t.componentGroups { if group.code != groupCode { continue } for _, component := range group.components { if relay, ok := component.(*Relay); ok && relay.code == relayCode { return relay } } } return nil } func (t *Turnout) GetPhysicalSection() *PhysicalSection { return t.section } func (t *Turnout) GindDevicePortByPort(port proto.Port) DevicePort { return t.findDevicePortByPort(port) } type TurnoutPort struct { turnout *Turnout port proto.Port } func (t *TurnoutPort) Port() proto.Port { return t.port } func (t *TurnoutPort) Device() PortedDevice { return t.turnout } func (t *TurnoutPort) Turnout() *Turnout { if t == nil { return nil } return t.turnout }