rts-sim-module/fi/pscada.go
2023-12-11 11:09:07 +08:00

252 lines
8.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package fi
import (
"fmt"
"joylink.club/ecs"
"joylink.club/rtsssimulation/component"
"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) (component.SwitchThreePosition, error) {
switch opt {
case StpOpened:
return component.StpOpened, nil
case StpClosedPosition1:
return component.StpClosedPosition1, nil
case StpClosedPosition2:
return component.StpClosedPosition2, nil
default:
return component.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) (component.HandcarPosition, error) {
switch opt {
case HpOpened:
return component.HpOpened, nil
case HpClosed:
return component.HpClosed, nil
case HpTest:
return component.HpTest, nil
default:
return component.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
}