2023-09-06 16:20:36 +08:00
|
|
|
|
package repository
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2023-11-09 13:09:01 +08:00
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
"joylink.club/rtsssimulation/repository/model/proto"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Turnout struct {
|
|
|
|
|
Identity
|
|
|
|
|
|
|
|
|
|
// 岔心的公里标
|
2023-09-21 16:28:13 +08:00
|
|
|
|
km *proto.Kilometer
|
|
|
|
|
switchMachineType proto.Turnout_SwitchMachineType
|
2023-09-06 16:20:36 +08:00
|
|
|
|
|
|
|
|
|
// 道岔关联的道岔物理区段
|
|
|
|
|
section *PhysicalSection
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
// A/B/C端口关联的设备端口(区段/道岔)
|
2023-09-06 16:20:36 +08:00
|
|
|
|
aDevicePort DevicePort
|
|
|
|
|
bDevicePort DevicePort
|
|
|
|
|
cDevicePort DevicePort
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
// A/B/C端口关联的Link端口
|
|
|
|
|
aLinkPort *LinkPort
|
|
|
|
|
bLinkPort *LinkPort
|
|
|
|
|
cLinkPort *LinkPort
|
|
|
|
|
|
2023-09-20 18:20:56 +08:00
|
|
|
|
// A/B/C端口的边界的公里标
|
2023-09-06 16:20:36 +08:00
|
|
|
|
aKm *proto.Kilometer
|
|
|
|
|
bKm *proto.Kilometer
|
|
|
|
|
cKm *proto.Kilometer
|
|
|
|
|
|
2023-09-20 18:20:56 +08:00
|
|
|
|
// A/B/C端口的边界在Link上的位置
|
|
|
|
|
aLinkPosition *LinkPosition
|
|
|
|
|
bLinkPosition *LinkPosition
|
|
|
|
|
cLinkPosition *LinkPosition
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
// A/B/C方向关联的设备(目前有信号机、应答器、(非区段边界)检测点)
|
|
|
|
|
aDevices []Identity
|
|
|
|
|
bDevices []Identity
|
|
|
|
|
cDevices []Identity
|
2023-09-22 15:38:24 +08:00
|
|
|
|
|
2023-09-28 14:10:15 +08:00
|
|
|
|
componentGroups []*ElectronicComponentGroup
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 16:28:13 +08:00
|
|
|
|
func NewTurnout(id string, km *proto.Kilometer, switchMachineType proto.Turnout_SwitchMachineType) *Turnout {
|
2023-09-06 16:20:36 +08:00
|
|
|
|
return &Turnout{
|
2023-09-21 16:28:13 +08:00
|
|
|
|
Identity: identity{id, proto.DeviceType_DeviceType_Turnout},
|
|
|
|
|
km: km,
|
|
|
|
|
switchMachineType: switchMachineType,
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-25 15:39:03 +08:00
|
|
|
|
// FindCircuitRoleById 根据继电器id获取在具体电路中的电路角色
|
|
|
|
|
// relayId-继电器id
|
|
|
|
|
// relayGroup-继电器组合类型
|
|
|
|
|
// relayName-继电器在电路中的名称
|
|
|
|
|
// find-true找到,false未找到
|
|
|
|
|
func (t *Turnout) FindCircuitRoleById(relayId string) (relayGroup string, relayName string, find bool) {
|
2023-09-28 14:10:15 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-09-25 15:39:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "", "", false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FindRelayModelByCRole 根据继电器具体电路角色来获取继电器设备模型
|
|
|
|
|
// relayGroup-继电器组合类型
|
|
|
|
|
// relayName-继电器在电路中的名称
|
|
|
|
|
func (t *Turnout) FindRelayModelByCRole(relayGroup string, relayName string) Identity {
|
2023-09-28 14:10:15 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-09-25 15:39:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-09-06 16:20:36 +08:00
|
|
|
|
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 {
|
2023-12-05 15:01:34 +08:00
|
|
|
|
return fmt.Errorf("道岔不能与[%s]类型的设备端口关联", devicePort.Device().Type())
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
t.aDevicePort = devicePort
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
t.bDevicePort = devicePort
|
|
|
|
|
case proto.Port_C:
|
|
|
|
|
t.cDevicePort = devicePort
|
|
|
|
|
default:
|
2023-12-05 15:01:34 +08:00
|
|
|
|
return fmt.Errorf("道岔无端口[%s]", port)
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
func (t *Turnout) bindLinkPort(port proto.Port, linkPort *LinkPort) {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
t.aLinkPort = linkPort
|
|
|
|
|
case proto.Port_B:
|
2023-09-20 18:20:56 +08:00
|
|
|
|
t.bLinkPort = linkPort
|
2023-09-20 15:14:38 +08:00
|
|
|
|
case proto.Port_C:
|
2023-09-20 18:20:56 +08:00
|
|
|
|
t.cLinkPort = linkPort
|
2023-09-20 15:14:38 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
func (t *Turnout) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
|
2023-12-05 16:31:18 +08:00
|
|
|
|
if km == nil || (km.CoordinateSystem == "" && km.Value == 0) {
|
2023-12-05 15:01:34 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-09-06 16:20:36 +08:00
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
t.aKm = km
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
t.bKm = km
|
|
|
|
|
case proto.Port_C:
|
|
|
|
|
t.cKm = km
|
|
|
|
|
default:
|
2023-12-05 15:01:34 +08:00
|
|
|
|
return fmt.Errorf("道岔无端口[%s]", port)
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 18:20:56 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取指定端口连接的设备端口
|
2023-09-20 18:20:56 +08:00
|
|
|
|
func (t *Turnout) findDevicePortByPort(port proto.Port) DevicePort {
|
2023-09-06 16:20:36 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 18:20:56 +08:00
|
|
|
|
func (t *Turnout) findDevicesByPort(port proto.Port) []Identity {
|
2023-09-06 16:20:36 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 18:20:56 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-11-10 16:03:33 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-09-21 16:28:13 +08:00
|
|
|
|
func (t *Turnout) SwitchMachineType() proto.Turnout_SwitchMachineType {
|
|
|
|
|
return t.switchMachineType
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 17:10:33 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 14:10:15 +08:00
|
|
|
|
func (t *Turnout) RelayGroups() []*ElectronicComponentGroup {
|
|
|
|
|
return t.componentGroups
|
2023-09-26 10:25:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Turnout) FindRelay(groupCode, relayCode string) *Relay {
|
2023-09-28 14:10:15 +08:00
|
|
|
|
for _, group := range t.componentGroups {
|
2023-09-26 10:25:00 +08:00
|
|
|
|
if group.code != groupCode {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-09-28 14:10:15 +08:00
|
|
|
|
for _, component := range group.components {
|
|
|
|
|
if relay, ok := component.(*Relay); ok && relay.code == relayCode {
|
2023-09-26 10:25:00 +08:00
|
|
|
|
return relay
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-09 13:09:01 +08:00
|
|
|
|
func (t *Turnout) GetPhysicalSection() *PhysicalSection {
|
|
|
|
|
return t.section
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-09 13:16:42 +08:00
|
|
|
|
func (t *Turnout) GindDevicePortByPort(port proto.Port) DevicePort {
|
|
|
|
|
return t.findDevicePortByPort(port)
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-09-20 18:20:56 +08:00
|
|
|
|
|
|
|
|
|
func (t *TurnoutPort) Turnout() *Turnout {
|
2024-01-18 10:08:53 +08:00
|
|
|
|
if t == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-09-20 18:20:56 +08:00
|
|
|
|
return t.turnout
|
|
|
|
|
}
|