using System; using System.Xml; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using Aitex.Platform; namespace Aitex.Core.RT.Device.Unit { public class IoRf : BaseDevice, IDevice { //IO public bool IsOffline { get { return _diOffline != null && _diOffline.RawData; } } public float ScalePower { get { return _scPowerRange == null ? 99999 : (float)_scPowerRange.Value; } } public float ScaleFrequency { get { return 1000; } } public float ScaleDuty { get { return 100; } } public string UnitPower { get { return "w"; } } public string UnitFrequency { get { return "Hz"; } } public string UnitDuty { get { return "%"; } } [Subscription(AITRfProperty.IsOverTemp)] public bool IsOverTemp { get { return _diOverTemp != null && _diOverTemp.Value; } } [Subscription(AITRfProperty.RFEnable)] public bool IsRfOn //True:on { get { if (_diStatus != null) return _diStatus.Value; return _doPowerOn.Value; } } [Subscription(AITRfProperty.RFSetPoint)] public float PowerSetPoint { get { return _aoPower.Value; } set { _aoPower.Value = value; } } [Subscription(AITRfProperty.RFDuty)] public float DutySetPoint { get { return _aoPulsingDutyCycle == null ? 0 : _aoPulsingDutyCycle.Value; } } [Subscription(AITRfProperty.RFFrequency)] public float FrequencySetPoint { get { return _aoPulsingFrency == null ? 0 : _aoPulsingFrency.Value; } } [Subscription(AITRfProperty.RFForwardPower)] public float RFForwardPower { get { if (_aiForwardPower == null) return 0; return (_scRegulationFactor != null && _scRegulationFactor.Value > 0) ? (float)(_aiForwardPower.Value / _scRegulationFactor.Value) : _aiForwardPower.Value; } } [Subscription(AITRfProperty.RFReflectPower)] public float RFReflectPower { get { return _aiReflectedPower == null ? 0 : _aiReflectedPower.Value; } } [Subscription(AITRfProperty.RFInterlock)] public bool RFInterlock { get { return _diIntlk == null || _diIntlk.Value; } } [Subscription(AITRfProperty.RFMode)] public RfMode WorkMode { get { if (_aoWorkMode == null) return RfMode.ContinuousWaveMode; return Math.Abs(_aoWorkMode.Value - (int)RfMode.PulsingMode) < 0.1 ? RfMode.PulsingMode : RfMode.ContinuousWaveMode; } } public float MatchMode { get { if (_aiMatchMode != null) return _aiMatchMode.Value; return _aoMatchMode == null ? 0 : _aoMatchMode.Value; } } public int MatchProcessMode { get { return null == _aiMatchPresetMode ? 0 : (int)_aiMatchPresetMode.Value; } } [Subscription(AITRfProperty.RFMatchPositionC1Feedback)] public float MatchPositionC1 { get { if (_aiMatchPositionC1 != null) return _aiMatchPositionC1.Value; return 0; } } [Subscription(AITRfProperty.RFMatchPositionC2Feedback)] public float MatchPositionC2 { get { if (_aiMatchPositionC2 != null) return _aiMatchPositionC2.Value; return 0; } } [Subscription(AITRfProperty.RFMatchPositionC1SetPoint)] public float MatchPositionC1SetPoint { get { if (_aoMatchPositionC1 != null) return _aoMatchPositionC1.Value; return 0; } } [Subscription(AITRfProperty.RFMatchPositionC2SetPoint)] public float MatchPositionC2SetPoint { get { if (_aoMatchPositionC2 != null) return _aoMatchPositionC2.Value; return 0; } } [Subscription(AITRfProperty.Voltage)] public float Voltage { get { return _aiVoltage == null ? 0 : _aiVoltage.Value; } } [Subscription(AITRfProperty.Current)] public float Current { get { return _aiCurrent == null ? 0 : _aiCurrent.Value; } } private DateTime _powerOnStartTime; private TimeSpan _powerOnElapsedTime; public string PowerOnTime { get { if (IsRfOn) _powerOnElapsedTime = DateTime.Now - _powerOnStartTime; return string.Format("{0}:{1}:{2}", ((int)_powerOnElapsedTime.TotalHours).ToString("00"), _powerOnElapsedTime.Minutes.ToString("00"), (_powerOnElapsedTime.Seconds > 0 ? (_powerOnElapsedTime.Seconds + 1) : 0).ToString("00")); } } public bool EnablePulsing { get { return _scEnablePulsingFunction == null || _scEnablePulsingFunction.Value; } } public bool EnableC1C2Position { get { return _scEnableC1C2Position == null || _scEnableC1C2Position.Value; } } public bool EnableReflectPower { get { return _scEnableReflectPower == null || _scEnableReflectPower.Value; } } public bool EnableVoltageCurrent { get { return _scEnableVoltageCurrent == null || _scEnableVoltageCurrent.Value; } } private DIAccessor _diStatus = null; private DIAccessor _diIntlk = null; private DIAccessor _diOffline; private DIAccessor _diOverTemp; private DIAccessor _diIArc; private DIAccessor _diVArc; private DIAccessor _diBreakState; private DIAccessor _diHighReflectPower; private DIAccessor _diMatchCommWithGenerator; private DIAccessor _diRFCBAlarm; private DOAccessor _doPowerOn = null; private AIAccessor _aiReflectedPower = null; private AIAccessor _aiForwardPower = null; private AIAccessor _aiMatchPresetMode = null; private AIAccessor _aiMatchMode = null; private AIAccessor _aiMatchPositionC1 = null; private AIAccessor _aiMatchPositionC2 = null; private AIAccessor _aiVoltage; private AIAccessor _aiCurrent; private AOAccessor _aoPower = null; private AOAccessor _aoWorkMode = null; private AOAccessor _aoPulsingFrency = null; private AOAccessor _aoPulsingDutyCycle = null; private AOAccessor _aoMatchPresetMode = null; private AOAccessor _aoMatchMode = null; private AOAccessor _aoMatchPositionC1 = null; private AOAccessor _aoMatchPositionC2 = null; private AOAccessor _aoCoefficient = null; //SC private SCItem _scMatchPresetMode = null; private SCItem _scMatchMode = null; private SCItem _scMatchPositionC1 = null; private SCItem _scMatchPositionC2 = null; private SCItem _scPowerAlarmRange = null; private SCItem _scPowerAlarmTime = null; private SCItem _scReflectPowerAlarmRange = null; private SCItem _scReflectPowerAlarmTime = null; private SCItem _scPowerRange; private SCItem _scCoefficient; private SCItem _scEnablePulsingFunction; private SCItem _scEnableC1C2Position; private SCItem _scEnableReflectPower; private SCItem _scEnableVoltageCurrent; private SCItem _scRegulationFactor; private F_TRIG _interlockTrig = new F_TRIG(); private R_TRIG _rfOnTrigger = new R_TRIG(); private R_TRIG _trigOffline = new R_TRIG(); private R_TRIG _trigOverTemp = new R_TRIG(); private ToleranceChecker _checkerPower; private ToleranceChecker _checkerReflectPower; private R_TRIG _trigHighReflectPower = new R_TRIG(); private R_TRIG _trigMatchCommWithGenerator = new R_TRIG(); private R_TRIG _trigRFCBAlarm=new R_TRIG(); readonly DeviceTimer _powerOnTimer = new DeviceTimer(); public IoRf(string module, XmlElement node) { base.Module = module; base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); _diStatus = ParseDiNode("diOnOffFeedback", node); _diOffline = ParseDiNode("diOffline", node); _diIntlk = ParseDiNode("diInterlock", node); _diOverTemp = ParseDiNode("diOverTemp", node); _diIArc = ParseDiNode("diIArc", node); _diVArc = ParseDiNode("diVArc", node); _diBreakState = ParseDiNode("diBreakerState", node); _diHighReflectPower = ParseDiNode("diHighReflectPower", node); _diMatchCommWithGenerator = ParseDiNode("diMatchCommWithGenerator", node); _diRFCBAlarm = ParseDiNode("diRFCBAlarm", node); _doPowerOn = ParseDoNode("doOnOff", node); _aiReflectedPower = ParseAiNode("aiReflectPower", node); _aiForwardPower = ParseAiNode("aiForwardPower", node); _aiMatchPresetMode = ParseAiNode("aiMatchPresetMode", node); _aiMatchMode = ParseAiNode("aiMatchMode", node); _aiMatchPositionC1 = ParseAiNode("aiMatchPositionC1", node); _aiMatchPositionC2 = ParseAiNode("aiMatchPositionC2", node); _aiVoltage = ParseAiNode("aiVoltage", node); _aiCurrent = ParseAiNode("aiCurrent", node); _aoPower = ParseAoNode("aoPower", node); _aoWorkMode = ParseAoNode("aoWorkMode", node); _aoPulsingFrency = ParseAoNode("aoFrequency", node); _aoPulsingDutyCycle = ParseAoNode("aoDuty", node); _aoMatchPresetMode = ParseAoNode("aoMatchPresetMode", node); _aoMatchMode = ParseAoNode("aoMatchMode", node); _aoMatchPositionC1 = ParseAoNode("aoMatchPositionC1", node); _aoMatchPositionC2 = ParseAoNode("aoMatchPositionC2", node); _aoCoefficient = ParseAoNode("aoCoefficient", node); _scMatchPresetMode = ParseScNodeInteger("scMatchPresetMode", node); _scMatchMode = ParseScNodeInteger("scMatchMode", node); _scMatchPositionC1 = ParseScNodeDouble("scMatchPositionC1", node); _scMatchPositionC2 = ParseScNodeDouble("scMatchPositionC2", node); _scPowerAlarmRange = ParseScNodeDouble("scPowerAlarmRange", node); _scPowerAlarmTime = ParseScNodeDouble("scPowerAlarmTime", node); _scReflectPowerAlarmRange = ParseScNodeDouble("scReflectPowerAlarmRange", node); _scReflectPowerAlarmTime = ParseScNodeDouble("scReflectPowerAlarmTime", node); _scPowerRange = ParseScNodeDouble("scPowerRange", node); _scCoefficient = ParseScNodeDouble("scCoefficient", node); _scEnablePulsingFunction = ParseScNodeBool("scEnablePulsingFunction", node); _scEnableC1C2Position = ParseScNodeBool("scEnableC1C2Position", node); _scEnableReflectPower = ParseScNodeBool("scEnableReflectPower", node); _scEnableVoltageCurrent = ParseScNodeBool("scEnableVoltageCurrent", node); _scRegulationFactor = ParseScNodeDouble("scPowerRegulationFactor", node); } public bool Initialize() { DATA.Subscribe(string.Format("Device.{0}.{1}", Module, Name), () => { AITRfData data = new AITRfData() { DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = Display, ForwardPower = RFForwardPower, ReflectPower = RFReflectPower, IsInterlockOk = RFInterlock, IsRfOn = IsRfOn, PowerSetPoint = PowerSetPoint, FrequencySetPoint = FrequencySetPoint, DutySetPoint = DutySetPoint, ScalePower = ScalePower, ScaleDuty = ScaleDuty, ScaleFrequency = ScaleFrequency, UnitDuty = UnitDuty, UnitFrequency = UnitFrequency, UnitPower = UnitPower, WorkMode = (int)WorkMode, PowerOnElapsedTime = PowerOnTime, EnablePulsing = EnablePulsing, EnableC1C2Position = EnableC1C2Position, EnableReflectPower = EnableReflectPower, EnableVoltageCurrent = EnableVoltageCurrent, MatchMode = (int)MatchMode, MatchPresetMode = MatchProcessMode, MatchPositionC1 = MatchPositionC1, MatchPositionC2 = MatchPositionC2, MatchPositionC1SetPoint = MatchPositionC1SetPoint, MatchPositionC2SetPoint = MatchPositionC2SetPoint, Voltage = Voltage, Current = Current, }; return data; }, SubscriptionAttribute.FLAG.IgnoreSaveDB); if (_aoWorkMode != null) _aoWorkMode.Value = (float)RfMode.ContinuousWaveMode; if (_aoMatchMode != null) _aoMatchMode.Value = _scMatchMode != null ? _scMatchMode.Value : 0; if (_aoMatchPositionC1 != null) _aoMatchPositionC1.Value = _scMatchPositionC1 != null ? (float)_scMatchPositionC1.Value : 50; if (_aoMatchPositionC2 != null) _aoMatchPositionC2.Value = _scMatchPositionC2 != null ? (float)_scMatchPositionC2.Value : 50; //if (_aoMatchPresetMode != null) // _aoMatchPresetMode.Value = _scMatchPresetMode != null ? _scMatchPresetMode.Value : (int)RfMatchPresetMode.Hold; DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetPowerOnOff), (out string reason, int time, object[] param) => { bool isOn = Convert.ToBoolean((string)param[0]); bool res = this.SetPowerOnOff(isOn, out string str); reason = str; return res; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMode), (out string reason, int time, object[] param) => { reason = string.Empty; RfMode mode = (RfMode)Enum.Parse(typeof(RfMode), (string)param[0], true); if (_aoWorkMode != null) { _aoWorkMode.Value = mode == RfMode.ContinuousWaveMode ? 1 : 2; } reason = string.Format("Set RF work mode to " + mode.ToString()); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetContinuousPower), (out string reason, int time, object[] param) => { float power = (float)Convert.ToDouble((string)param[0]); power = Math.Max(0, power); power = Math.Min(ScalePower, power); _aoPower.Value = power; reason = string.Format("RF set Power {0}", _aoPower.Value); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetPulsingPower), (out string reason, int time, object[] param) => { float frequency = (float)Convert.ToDouble((string)param[1]); frequency = Math.Max(0, frequency); frequency = Math.Min(ScaleFrequency, frequency); _aoPulsingFrency.Value = frequency; float duty = (float)Convert.ToDouble((string)param[2]); duty = Math.Max(0, duty); duty = Math.Min(ScaleDuty, duty); _aoPulsingDutyCycle.Value = duty; float power = (float)Convert.ToDouble((string)param[0]); power = Math.Max(0, power); power = Math.Min(ScalePower, power); _aoPower.Value = power; reason = string.Format("RF set Frequency:{0}, Duty:{1}, Power:{2}", frequency, duty, power); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetPulsingFrequency), (out string reason, int time, object[] param) => { reason = string.Empty; if (_aoPulsingFrency != null) { float frequency = (float)Convert.ToDouble((string)param[0]); frequency = Math.Max(0, frequency); frequency = Math.Min(ScaleFrequency, frequency); _aoPulsingFrency.Value = frequency; reason = string.Format("RF set Frequency:{0}", frequency); } return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetPulsingDuty), (out string reason, int time, object[] param) => { reason = string.Empty; if (_aoPulsingDutyCycle != null) { float duty = (float)Convert.ToDouble((string)param[0]); duty = Math.Max(0, duty); duty = Math.Min(ScaleDuty, duty); _aoPulsingDutyCycle.Value = duty; reason = string.Format("RF set Duty:{0} ", duty); } return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetPower), (out string reason, int time, object[] param) => { reason = string.Empty; float power = (float)Convert.ToDouble((string)param[0]); power = Math.Max(0, power); power = Math.Min(ScalePower, power); _aoPower.Value = power; reason = string.Format("RF set Power:{0}", power); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMatchPositionC1), (out string reason, int time, object[] param) => { float c1 = (float)Convert.ToDouble((string)param[0]); c1 = Math.Max((float)_scMatchPositionC1.RangeLowLimit, c1); c1 = Math.Min((float)_scMatchPositionC1.RangeUpLimit, c1); _aoMatchPositionC1.Value = c1; reason = string.Format("Set RF match position c1 :{0}", c1); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMatchPositionC2), (out string reason, int time, object[] param) => { float c2 = (float)Convert.ToDouble((string)param[0]); c2 = Math.Max((float)_scMatchPositionC1.RangeLowLimit, c2); c2 = Math.Min((float)_scMatchPositionC1.RangeUpLimit, c2); _aoMatchPositionC2.Value = c2; reason = string.Format("Set RF match position c2 :{0}", c2); return true; }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMatchPosition), (out string reason, int time, object[] param) => { return SetMatchPosition(Convert.ToDouble((string)param[0]), Convert.ToDouble((string)param[1]), out reason); }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMatchMode), (out string reason, int time, object[] param) => { return SetMatchMode(Convert.ToInt32((string)param[0]), out reason); }); DEVICE.Register(String.Format("{0}.{1}", Name, AITRfOperation.SetMatchProcessMode), (out string reason, int time, object[] param) => { RfMatchModeProcess mode = (RfMatchModeProcess)Enum.Parse(typeof(RfMatchModeProcess), (string)param[0], true); _aoMatchPresetMode.Value = (float)mode; reason = $"Match mode set to {mode}"; return true; }); return true; } public void Stop() { string reason = String.Empty; _aoPower.Value = 0; } public void Terminate() { } public void Monitor() { try { if (_powerOnTimer.IsTimeout() && !_diStatus.Value) { EV.PostMessage(Module, EventEnum.DefaultAlarm, "The RF generator is offline"); SetPowerOnOff(false, out string str); _powerOnTimer.Stop(); } if (_aoCoefficient != null && _scCoefficient != null) { _aoCoefficient.Value = (float)_scCoefficient.Value; } if (_checkerPower == null) _checkerPower = new ToleranceChecker(_scPowerAlarmTime.Value); if (_checkerReflectPower == null) _checkerReflectPower = new ToleranceChecker(_scReflectPowerAlarmTime.Value); _interlockTrig.CLK = _diIntlk.Value; if (_interlockTrig.Q) { EV.PostMessage(Module, EventEnum.RFInterlockFailed); } _rfOnTrigger.CLK = IsRfOn; if (_rfOnTrigger.Q) { _powerOnStartTime = DateTime.Now; _checkerPower.Reset(_scPowerAlarmTime.Value); _checkerReflectPower.Reset(_scReflectPowerAlarmTime.Value); } if (_rfOnTrigger.M) { _checkerPower.Monitor(RFForwardPower, PowerSetPoint - _scPowerAlarmRange.Value, PowerSetPoint + _scPowerAlarmRange.Value, _scPowerAlarmTime.Value); if (_checkerPower.Trig) { string reason; EV.PostMessage(Module, EventEnum.ToleranceAlarm, Module, Display, String.Format("Forward power {3} out of range[{0},{1}] in {2} seconds", (PowerSetPoint - _scPowerAlarmRange.Value).ToString("0"), (PowerSetPoint + _scPowerAlarmRange.Value).ToString("0"), _scPowerAlarmTime.Value.ToString("0"), RFForwardPower.ToString("0"))); SetPowerOnOff(false, out reason); } _checkerReflectPower.Monitor(RFReflectPower, double.MinValue, _scReflectPowerAlarmRange.Value, _scReflectPowerAlarmTime.Value); if (_checkerReflectPower.Trig) { string reason; EV.PostMessage(Module, EventEnum.ToleranceAlarm, Module, Display, String.Format("Reflect power {2} out of range[0,{0}] in {1} seconds", _scReflectPowerAlarmRange.Value.ToString("0"), _scReflectPowerAlarmTime.Value.ToString("0"), RFReflectPower.ToString("0"))); SetPowerOnOff(false, out reason); } } _trigOffline.CLK = IsOffline; if (_trigOffline.Q) { EV.PostMessage(Module, EventEnum.DefaultAlarm, "The RF generator is offline"); } _trigOverTemp.CLK = IsOverTemp; if (_trigOverTemp.Q) { EV.PostMessage(Module, EventEnum.RfOverTemp); } if (_diHighReflectPower != null) { _trigHighReflectPower.CLK = _diHighReflectPower.Value; if (_trigOffline.Q) { EV.PostMessage(Module, EventEnum.DefaultAlarm, "RF trig high reflect power"); } } if (_diMatchCommWithGenerator != null) { _trigMatchCommWithGenerator.CLK = !_diMatchCommWithGenerator.Value; if (_trigMatchCommWithGenerator.Q) { EV.PostMessage(Module, EventEnum.DefaultAlarm, "RF trig match not communicate with generator"); } } _trigRFCBAlarm.CLK = _diRFCBAlarm !=null&& _diRFCBAlarm.Value; if (_trigRFCBAlarm.Q) { EV.PostMessage(Module, EventEnum.DefaultAlarm, "RF Circuit Broaker Trip Alarm"); } } catch (Exception ex) { LOG.Write(ex); throw ex; } } public void Reset() { _interlockTrig.RST = true; _trigOffline.RST = true; _trigOverTemp.RST = true; _trigMatchCommWithGenerator.RST = true; _trigHighReflectPower.RST = true; _trigRFCBAlarm.RST = true; } public bool SetPowerOnOff(bool isOn, out string reason) { if (!_diIntlk.Value) { reason = string.Format("RF interlock is not satisfied,can not be on"); return false; } if (!isOn) { PowerSetPoint = 0; } bool result = _doPowerOn.SetValue(isOn, out reason); if (result) { reason = string.Format("Set RF power " + (isOn ? "On" : "Off")); if (isOn) _powerOnTimer.Start(5000); else _powerOnTimer.Stop(); } else { EV.PostAlarmLog(Module, reason); } return result; } public bool SetMatchMode(int mode, out string reason) { if (_aoMatchMode == null) { reason = "System do not support setting match mode."; return false; } _aoMatchMode.Value = mode; reason = string.Format("Match mode set to {0} ", mode); return true; } public bool SetMatchPosition(double c1, double c2, out string reason) { reason = string.Empty; if (_scMatchPositionC1 != null && _aoMatchPositionC1 != null) { double c1FilterValue = c1; c1FilterValue = Math.Min(_scMatchPositionC1.RangeUpLimit, c1FilterValue); c1FilterValue = Math.Max(_scMatchPositionC2.RangeLowLimit, c1FilterValue); _aoMatchPositionC1.Value = (float)c1FilterValue; reason = string.Format("Match position C1 set to {0} ", c1FilterValue); } if (_scMatchPositionC2 != null && _aoMatchPositionC2 != null) { double c2FilterValue = c2; c2FilterValue = Math.Min(_scMatchPositionC2.RangeUpLimit, c2FilterValue); c2FilterValue = Math.Max(_scMatchPositionC2.RangeLowLimit, c2FilterValue); _aoMatchPositionC2.Value = (float)c2FilterValue; reason += string.Format("Match position C2 set to {0}", c2FilterValue); } return true; } } }