diff --git a/component/bas.go b/component/bas.go deleted file mode 100644 index a725643..0000000 --- a/component/bas.go +++ /dev/null @@ -1,27 +0,0 @@ -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/iscs_bas.go b/component/iscs_bas.go new file mode 100644 index 0000000..7f3df42 --- /dev/null +++ b/component/iscs_bas.go @@ -0,0 +1,38 @@ +package component + +import ( + "joylink.club/ecs" + "joylink.club/rtsssimulation/consts" +) + +//环境与设备监控系统BAS 相关组件定义 + +// Fan 风机设备 +// 正转即顺时针转-排风;反转即逆时针转-进风 +type Fan struct { + Fc bool //true-变频器开启 + Bypass bool //true-旁路开启 + SoftStart bool //true-软启开启 + Power int //风机电源,大于0接通正转相序电源,小于0接通反转相序电源,等于0关闭电源 +} + +// FanState 面向用户的风机状态 +type FanState struct { + Forward bool //true-正转;false-反转 + Running bool //true-运行;false-停止 + Fc bool //true-变频器开启 + Bypass bool //true-旁路开启 + SoftStart bool //true-软启开启 + HighSpeed bool //true-双速风机之扇叶高速运转 + SlowSpeed bool //true-双速风机之扇叶低速运转 + Exception consts.DeviceExceptionEnum //风机异常 +} + +var ( + FanType = ecs.NewComponentType[Fan]() //风机 + FanStateType = ecs.NewComponentType[FanState]() + + TwoSpeedFanTag = ecs.NewTag() //双速风机标签 + LowSpeedModeFanTag = ecs.NewTag() //双速风机低速运行模式标签 + HighSpeedModeFanTag = ecs.NewTag() //双速风机高速运行模式标签 +) diff --git a/component/pscada.go b/component/iscs_pscada.go similarity index 100% rename from component/pscada.go rename to component/iscs_pscada.go diff --git a/consts/iscs_bas.go b/consts/iscs_bas.go new file mode 100644 index 0000000..64313c8 --- /dev/null +++ b/consts/iscs_bas.go @@ -0,0 +1,12 @@ +package consts + +// DeviceExceptionEnum 设备例外枚举定义 +type DeviceExceptionEnum = int8 + +const ( + DeviceExceptionNon DeviceExceptionEnum = iota + DeviceCommunicationInterrupt //通信中断 + DeviceAbnormal //异常 + DeviceFault //故障 有预告信号产生 + DeviceAlarm //报警 有事故信号产生 +) diff --git a/consts/pscada.go b/consts/iscs_pscada.go similarity index 100% rename from consts/pscada.go rename to consts/iscs_pscada.go diff --git a/entity/iscs_bas.go b/entity/iscs_bas.go new file mode 100644 index 0000000..9356433 --- /dev/null +++ b/entity/iscs_bas.go @@ -0,0 +1 @@ +package entity diff --git a/fi/iscs_bas.go b/fi/iscs_bas.go new file mode 100644 index 0000000..f3da75e --- /dev/null +++ b/fi/iscs_bas.go @@ -0,0 +1,113 @@ +package fi + +import ( + "fmt" + "joylink.club/ecs" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/entity" +) + +// CommonFanOperate 一般风机控制,如排烟风机、正压送风机、射流风机、普通风机、硬线风机 +// +// power : 风机电源,大于0接通正转相序电源,小于0接通反转相序电源,等于0关闭电源 +func CommonFanOperate(w ecs.World, deviceId string, power int) 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.FanType) { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是风机", deviceId)) + } + // + fan := component.FanType.Get(deviceEntry) + fan.Power = power + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +// SoftBypassFanOperate 如软启风机、隧道风机 +func SoftBypassFanOperate(w ecs.World, deviceId string, power int, softStart bool, bypass 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.FanType) { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是风机", deviceId)) + } + // + fan := component.FanType.Get(deviceEntry) + fan.Bypass = bypass + fan.SoftStart = softStart + fan.Power = power + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +// FcBypassFanOperate (变频、旁路)回排风机 +func FcBypassFanOperate(w ecs.World, deviceId string, power int, fc bool, bypass 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.FanType) { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是风机", deviceId)) + } + // + fan := component.FanType.Get(deviceEntry) + fan.Bypass = bypass + fan.Fc = fc + fan.Power = power + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +// TwoSpeedFanOperate 双速风机,转速模式设置 +// +// highSpeedMode-true高速模式,false-低速模式 +func TwoSpeedFanOperate(w ecs.World, deviceId string, power int, highSpeedMode 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.FanType) && deviceEntry.HasComponent(component.TwoSpeedFanTag)) { + return ecs.NewErrResult(fmt.Errorf("设备[%s]不是双速风机", deviceId)) + } + // + fan := component.FanType.Get(deviceEntry) + fan.Power = power + // + deviceEntry.RemoveComponent(component.HighSpeedModeFanTag) + deviceEntry.RemoveComponent(component.LowSpeedModeFanTag) + if highSpeedMode { + deviceEntry.AddComponent(component.HighSpeedModeFanTag) + } else { + deviceEntry.AddComponent(component.LowSpeedModeFanTag) + } + // + return ecs.NewOkEmptyResult() + }) + return r.Err +} + +// FanExceptionOperate 风机异常设置(故障、异常、通信中断) +func FanExceptionOperate(w ecs.World, deviceId string, opt DeviceExceptionOptEnum) error { + return DeviceExceptionOperate(w, deviceId, opt) +} diff --git a/fi/pscada.go b/fi/iscs_pscada.go similarity index 100% rename from fi/pscada.go rename to fi/iscs_pscada.go diff --git a/sys/iscs_sys/iscs_bas_fan.go b/sys/iscs_sys/iscs_bas_fan.go new file mode 100644 index 0000000..ca1b072 --- /dev/null +++ b/sys/iscs_sys/iscs_bas_fan.go @@ -0,0 +1,43 @@ +package iscs_sys + +import ( + "joylink.club/ecs" + "joylink.club/ecs/filter" + "joylink.club/rtsssimulation/component" + "joylink.club/rtsssimulation/consts" +) + +// BasFanSystem ISCS BAS 风机 +type BasFanSystem struct { + query *ecs.Query +} + +func NewBasFanSystem() *BasFanSystem { + return &BasFanSystem{ + query: ecs.NewQuery(filter.Contains(component.FanType)), + } +} +func (s *BasFanSystem) Update(w ecs.World) { + s.query.Each(w, func(entry *ecs.Entry) { + fan := component.FanType.Get(entry) + // + fanState := component.FanStateType.Get(entry) + fanState.Fc = fan.Fc + fanState.Bypass = fan.Bypass + fanState.Running = fan.Power != 0 + fanState.Forward = fan.Power > 0 + fanState.SoftStart = fan.SoftStart + fanState.HighSpeed = fanState.Running && entry.HasComponent(component.HighSpeedModeFanTag) + fanState.SlowSpeed = fanState.Running && entry.HasComponent(component.LowSpeedModeFanTag) + // + if entry.HasComponent(component.DeviceFaultTag) { + fanState.Exception = consts.DeviceFault + } + if entry.HasComponent(component.DeviceAbnormalTag) { + fanState.Exception = consts.DeviceAbnormal + } + if entry.HasComponent(component.DeviceCommunicationInterruptTag) { + fanState.Exception = consts.DeviceCommunicationInterrupt + } + }) +}