From e974ac0f9309b697710fac54a65e467dd1faac01 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Fri, 8 Dec 2023 17:44:25 +0800 Subject: [PATCH 1/2] =?UTF-8?q?ISCS=E7=94=B5=E5=8A=9B=E7=B3=BB=E7=BB=9Fecs?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- component/bas.go | 27 +++ component/pscada.go | 117 +++++++++- consts/pscada.go | 31 +-- entity/pscada.go | 79 ++++++- fi/pscada.go | 252 +++++++++++++++++++++ sys/iscs_sys/iscs_circuit_breaker.go | 32 +++ sys/iscs_sys/iscs_handcart_switch.go | 34 +++ sys/iscs_sys/iscs_rectifier.go | 29 +++ sys/iscs_sys/iscs_three_position_switch.go | 38 ++++ sys/iscs_sys/iscs_trans_busbar.go | 31 +++ sys/iscs_sys/iscs_voltage_transformer.go | 32 +++ sys/iscs_sys/iscs_wire_cabinet.go | 29 +++ 12 files changed, 686 insertions(+), 45 deletions(-) create mode 100644 component/bas.go create mode 100644 fi/pscada.go create mode 100644 sys/iscs_sys/iscs_circuit_breaker.go create mode 100644 sys/iscs_sys/iscs_handcart_switch.go create mode 100644 sys/iscs_sys/iscs_rectifier.go create mode 100644 sys/iscs_sys/iscs_three_position_switch.go create mode 100644 sys/iscs_sys/iscs_trans_busbar.go create mode 100644 sys/iscs_sys/iscs_voltage_transformer.go create mode 100644 sys/iscs_sys/iscs_wire_cabinet.go diff --git a/component/bas.go b/component/bas.go new file mode 100644 index 0000000..a725643 --- /dev/null +++ b/component/bas.go @@ -0,0 +1,27 @@ +package component + +import "joylink.club/ecs" + +//环境与设备监控系统BAS 相关组件定义 + +// Fan 风机 +// 正转即顺时针转-排风;反转即逆时针转-进风 +type Fan struct { + //正转 反转 + //运行 停止 + //故障 + //变频 + //旁路 + //软启 + //高速 双速风机 + //低速 双速风机 + //异常、通信中断 + +} + +// 双速风机标签 +var ( + TwoSpeedFanTag = ecs.NewTag() //双速风机标签 + LowSpeedModeFanTag = ecs.NewTag() //双速风机低速运行模式标签 + HighSpeedModeFanTag = ecs.NewTag() //双速风机高速运行模式标签 +) diff --git a/component/pscada.go b/component/pscada.go index ceef9cc..87a8470 100644 --- a/component/pscada.go +++ b/component/pscada.go @@ -5,7 +5,91 @@ import ( "joylink.club/rtsssimulation/consts" ) -//电力系统相关组件定义 +//ISCS 电力系统相关组件定义 + +// IscsWireCabinetState ISCS线柜状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsWireCabinetState struct { + Normal bool //true-正常 + Fault bool //true-故障 + Alarm bool //true-报警 + Abnormal bool //true-通讯中断/异常 +} + +// IscsCircuitBreakerState ISCS断路器状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +// +// 断路器;PT、负极柜隔离开关、轨电位、上网隔离开关、隔离开关 +type IscsCircuitBreakerState struct { + Closed bool //true-合闸 + Opened bool //true-开闸 + Abnormal bool //true-通讯中断/异常 +} + +// IscsRectifierState ISCS整流器状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsRectifierState struct { + Normal bool //true-正常 + Fault bool //true-故障 + Alarm bool //true-报警 + CommunicationInterrupt bool //true-通讯中断 +} + +// IscsHandcartSwitchState ISCS手车状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsHandcartSwitchState struct { + WorkPosClosed bool //true-工作位合闸 + WorkPosOpened bool //true-工作位分闸 + TestPos bool //true-实验位 + CommunicationInterrupt bool //true-通讯中断 +} + +// IscsVoltageTransformerState ISCS变压器状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsVoltageTransformerState struct { + Normal bool //true-正常 + Fault bool //true-故障 (注意-变压器110kV/35kv没有此项) + Alarm bool //true-报警 + CommunicationInterrupt bool //true-通讯中断 +} + +// IscsThreePositionSwitchState ISCS三工位隔离开关状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsThreePositionSwitchState struct { + DisconnectSwitchClosed bool //true-隔离开关合闸 + LandingSwitchClosed bool //true-接地开关合闸 + Opened bool //true-开闸 + Abnormal bool //true-异常 + CommunicationInterrupt bool //true-通讯中断 +} + +// IscsTransBackupZiTouState ISCS母联备自投状态 +// +// 状态由该设备的其他组件运算得到,该状态组件对外为只读组件,面向用户 +type IscsTransBackupZiTouState struct { + Input bool //true-备自投投入 + Exit bool //true-备自投退出 + CommunicationInterrupt bool //true-通讯中断 +} + +// ISCS 相关设备状态组件 +var ( + IscsWireCabinetStateType = ecs.NewComponentType[IscsWireCabinetState]() + IscsCircuitBreakerStateType = ecs.NewComponentType[IscsCircuitBreakerState]() + IscsRectifierStateType = ecs.NewComponentType[IscsRectifierState]() + IscsHandcartSwitchStateType = ecs.NewComponentType[IscsHandcartSwitchState]() + IscsVoltageTransformerStateType = ecs.NewComponentType[IscsVoltageTransformerState]() + IscsIscsThreePositionSwitchStateType = ecs.NewComponentType[IscsThreePositionSwitchState]() + IscsTransBackupZiTouStateType = ecs.NewComponentType[IscsTransBackupZiTouState]() +) + +///////////////////////////////////////////////////////// // TransBusbar 输电母线 type TransBusbar struct { @@ -17,7 +101,7 @@ type TransBusbar struct { // 如断路器 // 如PT、负极柜隔离开关、轨电位、上网隔离开关、隔离开关 type TwoPositionSwitch struct { - Position consts.SwitchTwoPosition + Closed bool //true-合闸,线路导通;false-分闸,线路断开 } // ///////////////////////////////////////// @@ -25,7 +109,7 @@ type TwoPositionSwitch struct { // ThreePositionSwitch 三工位开关 // 对于三工位隔离开关,规定:ClosedPosition1-合闸到工作位,ClosedPosition2-合闸到接地位 type ThreePositionSwitch struct { - Position consts.SwitchThreePosition + Position consts.SwitchThreePosition //合闸到位置1,与位置1线路导通;合闸到位置2,与位置2线路导通;分闸,线路断开,未与任何位置接通 } ///////////////////////////////////////////// @@ -42,19 +126,32 @@ type HandcartSwitch struct { // Epu所有状态如:35kV进线柜、35kV出线柜、1500V直流进线柜、配电变馈线柜、整流变馈线柜、35kV母联柜、500V直流馈线柜、1500V直流馈线柜、1500V直流负极柜 // Epu状态中除去报警,如:400V进线柜、400V母联柜、三级负荷总开关、上网隔离开关柜、接口柜 type ElecDevice struct { - State consts.EpuStateEnum -} - -// DeviceNet 设备联网状态 -type DeviceNet struct { - Online bool //true-网络通信正常,false-通信中断 + Normal bool //true-正常 } +// 电力设备组件 var ( ElecDeviceType = ecs.NewComponentType[ElecDevice]() - DeviceNetType = ecs.NewComponentType[DeviceNet]() HandcartSwitchType = ecs.NewComponentType[HandcartSwitch]() ThreePositionSwitchType = ecs.NewComponentType[ThreePositionSwitch]() TwoPositionSwitchType = ecs.NewComponentType[TwoPositionSwitch]() TransBusbarType = ecs.NewComponentType[TransBusbar]() ) + +// 设备例外标签定义 +var ( + DeviceCommunicationInterruptTag = ecs.NewTag() //通信中断 + DeviceAbnormalTag = ecs.NewTag() //异常 + DeviceFaultTag = ecs.NewTag() //故障 有预告信号产生 + DeviceAlarmTag = ecs.NewTag() //报警 有事故信号产生 +) + +// 设备置牌标签定义 +var ( + DevicePlacingOverhaulCardTag = ecs.NewTag() //设备置牌:检修 + DevicePlacingLandingCardTag = ecs.NewTag() //设备置牌:接地 + DevicePlacingOtherCardTag = ecs.NewTag() //设备置牌:其他 +) + +// BackupZiTouInputTag 备自投投入、退出标签 +var BackupZiTouInputTag = ecs.NewTag() //备自投投入标签 diff --git a/consts/pscada.go b/consts/pscada.go index edec412..f24bbc3 100644 --- a/consts/pscada.go +++ b/consts/pscada.go @@ -24,35 +24,16 @@ const ( type SwitchThreePosition = uint8 const ( - StpClosedPosition1 SwitchThreePosition = iota + 1 //开关合闸到位置1,与位置1线路导通 - StpClosedPosition2 //开关合闸到位置2,与位置2线路导通 - StpOpened //开关分闸,线路断开,未与任何位置接通 - StpFault //异常 -) - -// SwitchTwoPosition 两工位开关位置定义 -type SwitchTwoPosition = uint8 - -const ( - S2pClosed SwitchTwoPosition = iota + 1 //开关合闸到位,与线路导通 - S2pOpened //开关分闸,线路断开,未与任何位置接通 - S2pFault //故障异常 + StpOpened SwitchThreePosition = iota //开关分闸,线路断开,未与任何位置接通 + StpClosedPosition1 //开关合闸到位置1,与位置1线路导通 + StpClosedPosition2 //开关合闸到位置2,与位置2线路导通 ) // HandcarPosition 手车式开关位置定义 type HandcarPosition = uint8 const ( - HpClosed HandcarPosition = iota + 1 //工作位合闸 - HpOpened //工作位分闸 - HpTest //实验位 -) - -// EpuStateEnum 一般电力设备状态定义 -type EpuStateEnum = uint8 - -const ( - EpuNormal EpuStateEnum = iota + 1 //正常 - EpuFault //故障,有预告信号产生 - EpuAlarm //报警,有事故信号产生 + HpOpened HandcarPosition = iota //工作位分闸 + HpClosed //工作位合闸 + HpTest //实验位 ) diff --git a/entity/pscada.go b/entity/pscada.go index 3fb32f5..992b616 100644 --- a/entity/pscada.go +++ b/entity/pscada.go @@ -6,23 +6,84 @@ import ( "joylink.club/rtsssimulation/consts" ) +// 电力监控系统相关实体创建 + +// NewIscsWireCabinetEntity ISCS创建线柜实体 +// +// 35kV进线柜、35kV出线柜、1500V直流进线柜、配电变馈线柜、整流变馈线柜、35kV母联柜、500V直流馈线柜、1500V直流馈线柜、1500V直流负极柜 +// 400V进线柜、400V母联柜、三级负荷总开关、上网隔离开关柜、接口柜 +func NewIscsWireCabinetEntity(w ecs.World, id string) *ecs.Entry { + entry := NewElectricPowerDeviceEntity(w, id) + entry.AddComponent(component.IscsWireCabinetStateType) + return entry +} + +// NewIscsCircuitBreakerEntity ISCS创建断路器实体 +// 断路器;PT、负极柜隔离开关、轨电位、上网隔离开关、隔离开关 +func NewIscsCircuitBreakerEntity(w ecs.World, id string) *ecs.Entry { + entry := NewTwoPositionSwitchEntity(w, id) + entry.AddComponent(component.IscsCircuitBreakerStateType) + return entry +} + +// NewIscsRectifierEntity ISCS创建整流器实体 +func NewIscsRectifierEntity(w ecs.World, id string) *ecs.Entry { + entry := NewElectricPowerDeviceEntity(w, id) + entry.AddComponent(component.IscsRectifierStateType) + return entry +} + +// NewIscsHandcartSwitchEntity ISCS创建手车实体 +func NewIscsHandcartSwitchEntity(w ecs.World, id string) *ecs.Entry { + entry := NewHandcartSwitchEntity(w, id) + entry.AddComponent(component.IscsHandcartSwitchStateType) + return entry +} + +// NewIscsVoltageTransformerEntity ISCS创建变压器实体 +func NewIscsVoltageTransformerEntity(w ecs.World, id string) *ecs.Entry { + entry := NewElectricPowerDeviceEntity(w, id) + entry.AddComponent(component.IscsVoltageTransformerStateType) + return entry +} + +// NewIscsThreePositionSwitchEntity ISCS创建三工位开关实体 +func NewIscsThreePositionSwitchEntity(w ecs.World, id string) *ecs.Entry { + entry := NewThreePositionSwitchEntity(w, id) + entry.AddComponent(component.IscsIscsThreePositionSwitchStateType) + return entry +} + +// NewIscsTransBusbarEntity ISCS创建输电母线 +func NewIscsTransBusbarEntity(w ecs.World, id string, haveBackupZiTou bool) *ecs.Entry { + entry := w.Entry(w.Create(component.UidType, component.TransBusbarType)) + component.UidType.SetValue(entry, component.Uid{Id: id}) + component.TransBusbarType.Set(entry, &component.TransBusbar{Vl: consts.VlNon, Elec: consts.EywLossing}) + // + if haveBackupZiTou { + entry.AddComponent(component.IscsTransBackupZiTouStateType) + } + // + return entry +} + +///////////////////////////////////////////通用///////////////////////////////////////////////////////// + // NewTwoPositionSwitchEntity 创建两工位开关实体 // 如断路器 // 如PT、负极柜隔离开关、轨电位、上网隔离开关、隔离开关 func NewTwoPositionSwitchEntity(w ecs.World, id string) *ecs.Entry { - e := w.Entry(w.Create(component.UidType, component.TwoPositionSwitchType, component.DeviceNetType)) + e := w.Entry(w.Create(component.UidType, component.TwoPositionSwitchType)) component.UidType.SetValue(e, component.Uid{Id: id}) - component.TwoPositionSwitchType.Set(e, &component.TwoPositionSwitch{Position: consts.S2pOpened}) - component.DeviceNetType.Set(e, &component.DeviceNet{Online: true}) + component.TwoPositionSwitchType.Set(e, &component.TwoPositionSwitch{Closed: false}) return e } // NewThreePositionSwitchEntity 创建三工位隔离开关实体 func NewThreePositionSwitchEntity(w ecs.World, id string) *ecs.Entry { - e := w.Entry(w.Create(component.UidType, component.ThreePositionSwitchType, component.DeviceNetType)) + e := w.Entry(w.Create(component.UidType, component.ThreePositionSwitchType)) component.UidType.SetValue(e, component.Uid{Id: id}) component.ThreePositionSwitchType.Set(e, &component.ThreePositionSwitch{Position: consts.StpOpened}) - component.DeviceNetType.Set(e, &component.DeviceNet{Online: true}) return e } @@ -31,19 +92,17 @@ func NewThreePositionSwitchEntity(w ecs.World, id string) *ecs.Entry { // Epu所有状态如:35kV进线柜、35kV出线柜、1500V直流进线柜、配电变馈线柜、整流变馈线柜、35kV母联柜、500V直流馈线柜、1500V直流馈线柜、1500V直流负极柜 // Epu状态中除去报警,如:400V进线柜、400V母联柜、三级负荷总开关、上网隔离开关柜、接口柜 func NewElectricPowerDeviceEntity(w ecs.World, id string) *ecs.Entry { - e := w.Entry(w.Create(component.UidType, component.ElecDeviceType, component.DeviceNetType)) + e := w.Entry(w.Create(component.UidType, component.ElecDeviceType)) component.UidType.SetValue(e, component.Uid{Id: id}) - component.ElecDeviceType.Set(e, &component.ElecDevice{State: consts.EpuNormal}) - component.DeviceNetType.Set(e, &component.DeviceNet{Online: true}) + component.ElecDeviceType.Set(e, &component.ElecDevice{Normal: true}) return e } // NewHandcartSwitchEntity 创建手车实体 func NewHandcartSwitchEntity(w ecs.World, id string) *ecs.Entry { - e := w.Entry(w.Create(component.UidType, component.ThreePositionSwitchType, component.DeviceNetType)) + e := w.Entry(w.Create(component.UidType, component.HandcartSwitchType)) component.UidType.SetValue(e, component.Uid{Id: id}) component.HandcartSwitchType.Set(e, &component.HandcartSwitch{Position: consts.HpOpened}) - component.DeviceNetType.Set(e, &component.DeviceNet{Online: true}) return e } diff --git a/fi/pscada.go b/fi/pscada.go new file mode 100644 index 0000000..a133a08 --- /dev/null +++ b/fi/pscada.go @@ -0,0 +1,252 @@ +package fi + +import ( + "fmt" + "joylink.club/ecs" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" + "joylink.club/rtsssimulation/entity" +) + +// PlacingCardOptEnum 设备置牌操作枚举定义 +type PlacingCardOptEnum = uint8 + +// 设备置牌操作枚举定义 +const ( + PlacingNonCard PlacingCardOptEnum = iota + PlacingOverhaulCard + PlacingLandingCard + PlacingOtherCard +) + +// DevicePlacingCardOperate 设备置牌操作 +func DevicePlacingCardOperate(w ecs.World, deviceId string, placingCard PlacingCardOptEnum) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("被置牌设备[%s]实体不存在", deviceId)) + } + clearAllPlacingTags := func(deviceEntry *ecs.Entry) { + deviceEntry.RemoveComponent(component.DevicePlacingLandingCardTag) + deviceEntry.RemoveComponent(component.DevicePlacingOverhaulCardTag) + deviceEntry.RemoveComponent(component.DevicePlacingOtherCardTag) + } + switch placingCard { + case PlacingLandingCard: + clearAllPlacingTags(deviceEntry) + deviceEntry.AddComponent(component.DevicePlacingLandingCardTag) + case PlacingOverhaulCard: + clearAllPlacingTags(deviceEntry) + deviceEntry.AddComponent(component.DevicePlacingOverhaulCardTag) + case PlacingOtherCard: + clearAllPlacingTags(deviceEntry) + deviceEntry.AddComponent(component.DevicePlacingOtherCardTag) + default: + clearAllPlacingTags(deviceEntry) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +////////////////////////////////////////////////////////////////// + +// TransBusbarBackupOperate 母线备自投投入操作 +func TransBusbarBackupOperate(w ecs.World, deviceId string, input bool) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("备自投母线[%s]实体不存在", deviceId)) + } + if input { + if !deviceEntry.HasComponent(component.BackupZiTouInputTag) { + deviceEntry.AddComponent(component.BackupZiTouInputTag) + } + } else { + if deviceEntry.HasComponent(component.BackupZiTouInputTag) { + deviceEntry.RemoveComponent(component.BackupZiTouInputTag) + } + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +/////////////////////////////////////////////////////////// + +// DeviceExceptionOptEnum 设备例外操作枚举定义 +type DeviceExceptionOptEnum = uint8 + +const ( + DeviceExceptionNon DeviceExceptionOptEnum = iota //无例外 + DeviceExceptionCommunicationInterrupt //通信中断 + DeviceExceptionAbnormal //异常 + DeviceExceptionFault //故障 有预告信号产生 + DeviceExceptionAlarm //报警 有事故信号产生 +) + +// DeviceExceptionOperate 设备例外操作 +func DeviceExceptionOperate(w ecs.World, deviceId string, opt DeviceExceptionOptEnum) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("设备[%s]实体不存在", deviceId)) + } + clearAllExceptions := func(deviceEntry *ecs.Entry) { + deviceEntry.RemoveComponent(component.DeviceCommunicationInterruptTag) + deviceEntry.RemoveComponent(component.DeviceAbnormalTag) + deviceEntry.RemoveComponent(component.DeviceFaultTag) + deviceEntry.RemoveComponent(component.DeviceAlarmTag) + } + // + switch opt { + case DeviceExceptionCommunicationInterrupt: + clearAllExceptions(deviceEntry) + deviceEntry.AddComponent(component.DeviceCommunicationInterruptTag) + case DeviceExceptionAlarm: + clearAllExceptions(deviceEntry) + deviceEntry.AddComponent(component.DeviceAlarmTag) + case DeviceExceptionAbnormal: + clearAllExceptions(deviceEntry) + deviceEntry.AddComponent(component.DeviceAbnormalTag) + case DeviceExceptionFault: + clearAllExceptions(deviceEntry) + deviceEntry.AddComponent(component.DeviceFaultTag) + default: + clearAllExceptions(deviceEntry) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +//////////////////////////////////////////////////////// + +// TwoPositionSwitchOperate 两工位开关操作 +// +// 如断路器 +// 如PT、负极柜隔离开关、轨电位、上网隔离开关、隔离开关 +// +// close true-合闸;false-开闸 +func TwoPositionSwitchOperate(w ecs.World, deviceId string, close bool) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("设备[%s]实体不存在", deviceId)) + } + // + if deviceEntry.HasComponent(component.TwoPositionSwitchType) { + component.TwoPositionSwitchType.Get(deviceEntry).Closed = close + } else { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是两工位开关", deviceId)) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +/////////////////////////////////////////////////////////// + +// SwitchThreePositionOptEnum 三工位开关操作枚举定义 +type SwitchThreePositionOptEnum = uint8 + +const ( + StpOpened SwitchThreePositionOptEnum = iota //开关分闸,线路断开,未与任何位置接通 + StpClosedPosition1 //开关合闸到位置1,与位置1线路导通 + StpClosedPosition2 //开关合闸到位置2,与位置2线路导通 +) + +// ThreePositionSwitchOperate 三工位开关操作 +func ThreePositionSwitchOperate(w ecs.World, deviceId string, opt SwitchThreePositionOptEnum) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("设备[%s]实体不存在", deviceId)) + } + // + optConvert := func(opt SwitchThreePositionOptEnum) (consts.SwitchThreePosition, error) { + switch opt { + case StpOpened: + return consts.StpOpened, nil + case StpClosedPosition1: + return consts.StpClosedPosition1, nil + case StpClosedPosition2: + return consts.StpClosedPosition2, nil + default: + return consts.StpOpened, fmt.Errorf("三工位开关操作[%d]不存在", opt) + } + } + // + if deviceEntry.HasComponent(component.ThreePositionSwitchType) { + position, e := optConvert(opt) + if e == nil { + component.ThreePositionSwitchType.Get(deviceEntry).Position = position + } else { + return ecs.NewErrResult(e) + } + } else { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是三工位开关", deviceId)) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +///////////////////////////////////////////////////////////// + +// HandcartSwitchOptEnum 手车式开关操作枚举定义 +type HandcartSwitchOptEnum = uint8 + +const ( + HpOpened HandcartSwitchOptEnum = iota //工作位分闸 + HpClosed //工作位合闸 + HpTest //实验位 +) + +// HandcartSwitchOperate 手车式开关操作 +func HandcartSwitchOperate(w ecs.World, deviceId string, opt HandcartSwitchOptEnum) error { + r := <-ecs.Request[ecs.EmptyType](w, func() ecs.Result[ecs.EmptyType] { + wd := entity.GetWorldData(w) + deviceEntry, ok := wd.EntityMap[deviceId] + if !ok { + return ecs.NewErrResult(fmt.Errorf("设备[%s]实体不存在", deviceId)) + } + // + optConvert := func(opt HandcartSwitchOptEnum) (consts.HandcarPosition, error) { + switch opt { + case HpOpened: + return consts.HpOpened, nil + case HpClosed: + return consts.HpClosed, nil + case HpTest: + return consts.HpTest, nil + default: + return consts.StpOpened, fmt.Errorf("手车式开关操作[%d]不存在", opt) + } + } + // + if deviceEntry.HasComponent(component.HandcartSwitchType) { + position, e := optConvert(opt) + if e == nil { + component.HandcartSwitchType.Get(deviceEntry).Position = position + } else { + return ecs.NewErrResult(e) + } + } else { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是手车式开关", deviceId)) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} diff --git a/sys/iscs_sys/iscs_circuit_breaker.go b/sys/iscs_sys/iscs_circuit_breaker.go new file mode 100644 index 0000000..d081ddb --- /dev/null +++ b/sys/iscs_sys/iscs_circuit_breaker.go @@ -0,0 +1,32 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" +) + +// IscsCircuitBreakerSystem ISCS 断路器 +type IscsCircuitBreakerSystem struct { + query *ecs.Query +} + +func NewIscsCircuitBreakerSystem() *IscsCircuitBreakerSystem { + return &IscsCircuitBreakerSystem{ + query: ecs.NewQuery(filter.Contains(component.IscsCircuitBreakerStateType, component.TwoPositionSwitchType)), + } +} +func (s *IscsCircuitBreakerSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsCircuitBreakerStateType.Get(entry) + tpSwitch := component.TwoPositionSwitchType.Get(entry) + // + state.Abnormal = entry.HasComponent(component.DeviceCommunicationInterruptTag) || entry.HasComponent(component.DeviceAbnormalTag) + if state.Abnormal { //当开关异常时,断开 + tpSwitch.Closed = false + } + // + state.Closed = tpSwitch.Closed + state.Opened = !tpSwitch.Closed + }) +} diff --git a/sys/iscs_sys/iscs_handcart_switch.go b/sys/iscs_sys/iscs_handcart_switch.go new file mode 100644 index 0000000..107e3c1 --- /dev/null +++ b/sys/iscs_sys/iscs_handcart_switch.go @@ -0,0 +1,34 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" +) + +type IscsHandcartSwitchSystem struct { + query *ecs.Query +} + +func NewIscsHandcartSwitchSystem() *IscsHandcartSwitchSystem { + return &IscsHandcartSwitchSystem{ + query: ecs.NewQuery(filter.Contains(component.IscsHandcartSwitchStateType, component.HandcartSwitchType)), + } +} +func (s *IscsHandcartSwitchSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsHandcartSwitchStateType.Get(entry) + hdSwitch := component.HandcartSwitchType.Get(entry) + // + state.CommunicationInterrupt = entry.HasComponent(component.DeviceCommunicationInterruptTag) + // + if state.CommunicationInterrupt { //不正常,开关断开 + hdSwitch.Position = consts.HpOpened + } + // + state.WorkPosClosed = hdSwitch.Position == consts.HpClosed + state.WorkPosOpened = hdSwitch.Position == consts.HpOpened + state.TestPos = hdSwitch.Position == consts.HpTest + }) +} diff --git a/sys/iscs_sys/iscs_rectifier.go b/sys/iscs_sys/iscs_rectifier.go new file mode 100644 index 0000000..cf84685 --- /dev/null +++ b/sys/iscs_sys/iscs_rectifier.go @@ -0,0 +1,29 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" +) + +// IscsRectifierSystem ISCS整流器 +type IscsRectifierSystem struct { + query *ecs.Query +} + +func NewIscsRectifierSystem() *IscsRectifierSystem { + return &IscsRectifierSystem{query: ecs.NewQuery(filter.Contains(component.IscsRectifierStateType, component.ElecDeviceType))} +} +func (s *IscsRectifierSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsRectifierStateType.Get(entry) + // + state.Fault = entry.HasComponent(component.DeviceFaultTag) + state.Alarm = entry.HasComponent(component.DeviceAlarmTag) + state.CommunicationInterrupt = entry.HasComponent(component.DeviceCommunicationInterruptTag) + // + component.ElecDeviceType.Get(entry).Normal = !state.Fault && !state.Alarm && !state.CommunicationInterrupt + // + state.Normal = component.ElecDeviceType.Get(entry).Normal + }) +} diff --git a/sys/iscs_sys/iscs_three_position_switch.go b/sys/iscs_sys/iscs_three_position_switch.go new file mode 100644 index 0000000..e777234 --- /dev/null +++ b/sys/iscs_sys/iscs_three_position_switch.go @@ -0,0 +1,38 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" +) + +// IscsThreePositionSwitchSystem 三工位开关 +type IscsThreePositionSwitchSystem struct { + query *ecs.Query +} + +func NewIscsThreePositionSwitchSystem() *IscsThreePositionSwitchSystem { + return &IscsThreePositionSwitchSystem{ + query: ecs.NewQuery(filter.Contains(component.IscsIscsThreePositionSwitchStateType, component.ThreePositionSwitchType)), + } +} +func (s *IscsThreePositionSwitchSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsIscsThreePositionSwitchStateType.Get(entry) + tpSwitch := component.ThreePositionSwitchType.Get(entry) + // + state.Abnormal = entry.HasComponent(component.DeviceAbnormalTag) + state.CommunicationInterrupt = entry.HasComponent(component.DeviceCommunicationInterruptTag) + // + isTpSwitchNormal := !state.Abnormal && !state.CommunicationInterrupt + // + if !isTpSwitchNormal { //当开关不正常时,断开开关设备 + tpSwitch.Position = consts.StpOpened + } + // + state.Opened = tpSwitch.Position == consts.StpOpened + state.DisconnectSwitchClosed = tpSwitch.Position == consts.StpClosedPosition1 + state.LandingSwitchClosed = tpSwitch.Position == consts.StpClosedPosition2 + }) +} diff --git a/sys/iscs_sys/iscs_trans_busbar.go b/sys/iscs_sys/iscs_trans_busbar.go new file mode 100644 index 0000000..fa6bf9b --- /dev/null +++ b/sys/iscs_sys/iscs_trans_busbar.go @@ -0,0 +1,31 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" +) + +// IscsTransBusbarSystem ISCS电力母线 +type IscsTransBusbarSystem struct { + backupZiTouQuery *ecs.Query //备自投 +} + +func NewIscsTransBusbarSystem() *IscsTransBusbarSystem { + return &IscsTransBusbarSystem{ + backupZiTouQuery: ecs.NewQuery(filter.Contains(component.IscsTransBackupZiTouStateType)), + } +} +func (s *IscsTransBusbarSystem) Update(w ecs.World) { + s.backupZiTouQuery.Each(w, func(entry *ecs.Entry) { + s.calculateBackupZiTou(entry) + }) +} + +// 备自投 状态处理 +func (s *IscsTransBusbarSystem) calculateBackupZiTou(entry *ecs.Entry) { + ziTouState := component.IscsTransBackupZiTouStateType.Get(entry) + ziTouState.CommunicationInterrupt = entry.HasComponent(component.DeviceCommunicationInterruptTag) + ziTouState.Input = entry.HasComponent(component.BackupZiTouInputTag) + ziTouState.Exit = !entry.HasComponent(component.BackupZiTouInputTag) +} diff --git a/sys/iscs_sys/iscs_voltage_transformer.go b/sys/iscs_sys/iscs_voltage_transformer.go new file mode 100644 index 0000000..e886e3f --- /dev/null +++ b/sys/iscs_sys/iscs_voltage_transformer.go @@ -0,0 +1,32 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" +) + +// IscsVoltageTransformerSystem ISCS变压器 +type IscsVoltageTransformerSystem struct { + query *ecs.Query +} + +func NewIscsVoltageTransformerSystem() *IscsVoltageTransformerSystem { + return &IscsVoltageTransformerSystem{ + query: ecs.NewQuery(filter.Contains(component.IscsVoltageTransformerStateType, component.ElecDeviceType)), + } +} +func (s *IscsVoltageTransformerSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsVoltageTransformerStateType.Get(entry) + vt := component.ElecDeviceType.Get(entry) + // + state.Fault = entry.HasComponent(component.DeviceFaultTag) + state.Alarm = entry.HasComponent(component.DeviceAlarmTag) + state.CommunicationInterrupt = entry.HasComponent(component.DeviceCommunicationInterruptTag) + // + vt.Normal = !state.Fault && !state.Alarm && !state.CommunicationInterrupt + // + state.Normal = vt.Normal + }) +} diff --git a/sys/iscs_sys/iscs_wire_cabinet.go b/sys/iscs_sys/iscs_wire_cabinet.go new file mode 100644 index 0000000..881905e --- /dev/null +++ b/sys/iscs_sys/iscs_wire_cabinet.go @@ -0,0 +1,29 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" +) + +// IscsWireCabinetSystem ISCS 线柜 +type IscsWireCabinetSystem struct { + query *ecs.Query +} + +func NewIscsWireCabinetSystem() *IscsWireCabinetSystem { + return &IscsWireCabinetSystem{query: ecs.NewQuery(filter.Contains(component.IscsWireCabinetStateType, component.ElecDeviceType))} +} +func (s *IscsWireCabinetSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + state := component.IscsWireCabinetStateType.Get(entry) + // + state.Fault = entry.HasComponent(component.DeviceFaultTag) + state.Alarm = entry.HasComponent(component.DeviceAlarmTag) + state.Abnormal = entry.HasComponent(component.DeviceAbnormalTag) || entry.HasComponent(component.DeviceCommunicationInterruptTag) + // + component.ElecDeviceType.Get(entry).Normal = !state.Fault && !state.Alarm && !state.Abnormal + // + state.Normal = component.ElecDeviceType.Get(entry).Normal + }) +} From 357c6ad2c6949080f9790674b039e8cd70277344 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Fri, 8 Dec 2023 17:50:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?ISCS=E7=94=B5=E5=8A=9B=E7=B3=BB=E7=BB=9Fecs?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/{pscada.go => iscs_pscada.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename entity/{pscada.go => iscs_pscada.go} (100%) diff --git a/entity/pscada.go b/entity/iscs_pscada.go similarity index 100% rename from entity/pscada.go rename to entity/iscs_pscada.go