diff --git a/component/iscs_bas_valve.go b/component/iscs_bas_valve.go index 432d31d..f4eb17e 100644 --- a/component/iscs_bas_valve.go +++ b/component/iscs_bas_valve.go @@ -11,11 +11,15 @@ type Valve struct { Moving bool //true-正在动作 OpenRate uint8 //开度,0-100% } +type ValveController struct { + TargetOpenRate uint8 //目标开度,0-100% +} var ( ValveType = ecs.NewComponentType[Valve]() //阀门(开关) - ElectricControlValveTag = ecs.NewTag() //电动调节阀 - ElectricAirValveTag = ecs.NewTag() //电动风阀标签 - CombinationAirValveTag = ecs.NewTag() //组合式风阀 - ElectricButterflyValveTag = ecs.NewTag() //电动蝶阀 + ValveControllerType = ecs.NewComponentType[ValveController]() + ElectricControlValveTag = ecs.NewTag() //电动调节阀 + ElectricAirValveTag = ecs.NewTag() //电动风阀 + CombinationAirValveTag = ecs.NewTag() //组合式风阀 + ElectricButterflyValveTag = ecs.NewTag() //电动蝶阀 ) diff --git a/entity/iscs_bas.go b/entity/iscs_bas.go index e7703e1..37d7672 100644 --- a/entity/iscs_bas.go +++ b/entity/iscs_bas.go @@ -3,6 +3,8 @@ package entity import ( "joylink.club/ecs" "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/component/component_proto" + "joylink.club/rtsssimulation/consts" "joylink.club/rtsssimulation/repository/model/proto" ) @@ -57,9 +59,11 @@ func NewValveEntity(w ecs.World, id string, valveType proto.Valve_Type) *ecs.Ent wd := GetWorldData(w) e, ok := wd.EntityMap[id] if !ok { - e = w.Entry(w.Create(component.UidType, component.ValveType, component.DeviceExceptionType)) + e = w.Entry(w.Create(component.UidType, component.ValveType, component.ValveControllerType, component.TwoPositionTransformType, component.DeviceExceptionType)) component.UidType.SetValue(e, component.Uid{Id: id}) - component.ValveType.Set(e, &component.Valve{OpenRate: 100, Moving: false}) + //默认全关位置 + component.TwoPositionTransformType.Set(e, &component.TwoPositionTransform{TwoPositionTransform: component_proto.TwoPositionTransform{Pos: consts.TwoPosMin}}) + component.ValveControllerType.Set(e, &component.ValveController{TargetOpenRate: 0}) // switch valveType { case proto.Valve_ElectricControlValve: diff --git a/examples/main.go b/examples/main.go index 99447bb..2f86af2 100644 --- a/examples/main.go +++ b/examples/main.go @@ -34,7 +34,7 @@ func main() { } func newIscsSimulation(repo *repository.Repository) (ecs.World, error) { w := ecs.NewWorld(100) - sys.BindIscsSystem(w) + sys.BindSystem(w) // // 初始化世界数据单例组件 entity.LoadWorldData(w, repo) diff --git a/fi/iscs_bas.go b/fi/iscs_bas.go index db9b880..453e745 100644 --- a/fi/iscs_bas.go +++ b/fi/iscs_bas.go @@ -8,6 +8,31 @@ import ( "joylink.club/rtsssimulation/entity" ) +// ValveOperate 阀门操作 +// +// deviceId 阀门id; +// openRate 阀门打开百分比值,0-全关,100-全开; +func ValveOperate(w ecs.World, deviceId string, openRate uint8) error { + if openRate < 0 || openRate > 100 { + return fmt.Errorf("阀门打开百分比值[%d]不在范围[0,100]内", openRate) + } + 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.ValveType) && deviceEntry.HasComponent(component.ValveControllerType) && deviceEntry.HasComponent(component.TwoPositionTransformType)) { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是阀门", deviceId)) + } + component.ValveControllerType.Get(deviceEntry).TargetOpenRate = openRate + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + // PurificationDeviceOperate 净化装置操作 // // optStart : true-启动净化器;false-关停净化器 diff --git a/fi/motor.go b/fi/motor.go index 6965174..12af9fd 100644 --- a/fi/motor.go +++ b/fi/motor.go @@ -16,6 +16,11 @@ const ( FiMsOnReverse //反转电源 ) +// MotorOperate 电机操作 +// +// deviceId 电机id; +// fiMs 电机电源; +// fc 电机如果有变频器,设置频率; func MotorOperate(w ecs.World, deviceId string, fiMs FiMotorSwitch, fc uint16) error { if fc < 0 || fc > 100 { return fmt.Errorf("设置变频器频率[%d]不在[0,100]范围内", fc) diff --git a/sys/bind.go b/sys/bind.go index a8a97c8..c7804ec 100644 --- a/sys/bind.go +++ b/sys/bind.go @@ -40,11 +40,15 @@ func BindSystem(w ecs.World) { device_sys.NewSectionDetectSystem(), //应答器 device_sys.NewBaliseSystem(), + //电机 + device_sys.NewMotorSystem(), ) + //ISCS system + bindIscsSystem(w) } -// BindIscsSystem ISCS 系统 -func BindIscsSystem(w ecs.World) { +// bindIscsSystem ISCS 系统 +func bindIscsSystem(w ecs.World) { w.AddSystem( iscs_sys.NewIscsExceptionSystem(), iscs_sys.NewDevicePlacingSystem(), @@ -63,8 +67,6 @@ func BindIscsSystem(w ecs.World) { // iscs_sys.NewNetworkSwitchSystem(), iscs_sys.NewWireCabinetSystem(), - device_sys.NewMotorSystem(), iscs_sys.NewFanSystem(), iscs_sys.NewValveSystem()) - } diff --git a/sys/iscs_sys/iscs_bas_valve.go b/sys/iscs_sys/iscs_bas_valve.go index 83c5598..44e0e4d 100644 --- a/sys/iscs_sys/iscs_bas_valve.go +++ b/sys/iscs_sys/iscs_bas_valve.go @@ -1,9 +1,12 @@ package iscs_sys import ( + "fmt" "joylink.club/ecs" "joylink.club/ecs/filter" "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" + "joylink.club/rtsssimulation/entity" ) // ValveSystem 阀门 @@ -13,14 +16,46 @@ type ValveSystem struct { func NewValveSystem() *ValveSystem { return &ValveSystem{ - query: ecs.NewQuery(filter.Contains(component.UidType, component.ValveType, component.DeviceExceptionType)), + query: ecs.NewQuery(filter.Contains(component.UidType, component.ValveType, component.ValveControllerType, component.TwoPositionTransformType)), } } func (s *ValveSystem) Update(w ecs.World) { + wd := entity.GetWorldData(w) s.query.Each(w, func(entry *ecs.Entry) { + valveId := component.UidType.Get(entry).Id valve := component.ValveType.Get(entry) - valve.Closed = valve.OpenRate == 0 - valve.Opened = valve.OpenRate == 100 - + valveController := component.ValveControllerType.Get(entry) + position := component.TwoPositionTransformType.Get(entry) + // + valve.OpenRate = uint8((float64(position.Pos-consts.TwoPosMin) / float64(consts.TwoPosMax-consts.TwoPosMin)) * float64(100)) + valve.Closed = valve.OpenRate <= 0 + valve.Opened = valve.OpenRate >= 100 + valve.Moving = valve.OpenRate != valveController.TargetOpenRate + fmt.Printf("==>>阀门[%s],OpenRate = %d%% , 全开 = %t , 全关 = %t", valveId, valve.OpenRate, valve.Opened, valve.Closed) + // + valveModel, ok := wd.Repo.FindById(valveId).(valveModeler) + if !ok { + valveModel = vm + } + speed := int32((float64(consts.TwoPosMax-consts.TwoPosMin) / float64(valveModel.MaxMoveTime())) * float64(w.Tick())) + if valveController.TargetOpenRate < valve.OpenRate { + speed = -speed + } else if valveController.TargetOpenRate == valve.OpenRate { + speed = 0 + } }) } + +var vm = &valveModelDefault{maxMoveTime: 2500} + +type valveModeler interface { + //MaxMoveTime 阀门从全关到全开或从全开到全关耗时,单位ms + MaxMoveTime() uint16 +} +type valveModelDefault struct { + maxMoveTime uint16 +} + +func (v *valveModelDefault) MaxMoveTime() uint16 { + return v.maxMoveTime +}