using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using MECF.Framework.Common.CommonData; namespace MECF.Framework.Common.Device.Bases { public abstract class RfPowerBase : BaseDevice, IDevice { public virtual bool IsPowerOn { get; set; } public virtual bool IsMatchOn { get; set; } public virtual bool IsError { get; set; } public virtual bool IsMatchError { get; set; } public virtual EnumRfPowerWorkMode WorkMode { get; set; } public virtual EnumRfPowerControlMode ControlMode { get; set; } public virtual EnumRfPowerRegulationMode RegulationMode { get; set; } public virtual float ForwardPower { get; set; } public virtual float ReflectPower { get; set; } public virtual float PowerSetPoint { get; set; } public virtual float CLoadSet { get; set; } public virtual float CTuneSet { get; set; } public virtual float CLoad { get; set; } public virtual float CTune { get; set; } public virtual int VPP { get; set; } public virtual float Frequency { get; set; } public virtual float PulsingFrequency { get; set; } public virtual float PulsingDutyCycle { get; set; } public virtual float ScalePower { get; set; } public virtual AITRfPowerData DeviceData { get; set; } //calibration protected SCConfigItem _scEnableCalibration; protected SCConfigItem _scCalibrationTable; private List _calibrationTable = new List(); private string _previousSetting; protected float _recipeAlarmRange; protected float _recipeWarningRange; protected int _recipeIgnoreTimeMS; protected ToleranceChecker _recipeAlarmChecker = new ToleranceChecker(); protected ToleranceChecker _recipeWarningChecker = new ToleranceChecker(); protected DeviceTimer _recipeIgnoreTimer = new DeviceTimer(); protected ToleranceChecker _alarmChecker = new ToleranceChecker(); protected ToleranceChecker _warningChecker = new ToleranceChecker(); protected RfPowerBase( ) : base( ) { } protected RfPowerBase(string module, string name) : base(module, name, name, name) { } public virtual bool Initialize() { // DATA.Subscribe($"{Module}.{Name}.WorkMode", ()=>WorkMode.ToString()); DATA.Subscribe($"{Module}.{Name}.ControlMode", () => ControlMode.ToString()); DATA.Subscribe($"{Module}.{Name}.RegulationMode", () => RegulationMode.ToString()); DATA.Subscribe($"{Module}.{Name}.ForwardPower", () => ForwardPower); DATA.Subscribe($"{Module}.{Name}.ReflectPower", () => ReflectPower); DATA.Subscribe($"{Module}.{Name}.PowerSetPoint", () => PowerSetPoint); DATA.Subscribe($"{Module}.{Name}.IsPowerOn", () => IsPowerOn); DATA.Subscribe($"{Module}.{Name}.Frequency", () => Frequency); DATA.Subscribe($"{Module}.{Name}.PulsingFrequency", () => PulsingFrequency); DATA.Subscribe($"{Module}.{Name}.PulsingDutyCycle", () => PulsingDutyCycle); OP.Subscribe($"{Module}.{Name}.SetPowerOn", (function, args) => { return SetPowerOnOff(true, out string reason); }); OP.Subscribe($"{Module}.{Name}.SetPowerOff", (function, args) => { return SetPowerOnOff(false, out string reason); }); OP.Subscribe($"{Module}.{Name}.SetPower", (function, args) => { SetPower((float)args[0]); return true; }); OP.Subscribe($"{Module}.{Name}.SetRegulationMode", (function, args) => { if (!Enum.TryParse((string) args[0], out EnumRfPowerRegulationMode mode)) { EV.PostWarningLog(Module, $"Argument {args[0]}not valid"); return false; } SetRegulationMode(mode); return true; }); OP.Subscribe($"{Module}.{Name}.SetRecipeTolerance", (out string reason, int time, object[] param) => { reason = string.Empty; _recipeIgnoreTimeMS = Convert.ToInt32(param[0]) * 1000; _recipeWarningRange = Convert.ToSingle(param[1]); _recipeAlarmRange = Convert.ToSingle(param[2]); _recipeAlarmChecker.RST = true; _recipeWarningChecker.RST = true; if (_recipeIgnoreTimeMS > 0) _recipeIgnoreTimer.Start(0); return true; }); UpdateCalibrationTable(); return true; } public virtual void SetRegulationMode(EnumRfPowerRegulationMode enumRfPowerControlMode) { } public virtual bool SetPowerOnOff(bool isOn, out string reason) { reason = string.Empty; return true; } public virtual bool SetMatchingAutoMode(bool isOn, out string reason) { reason = string.Empty; return true; } public virtual bool SetMatchPosition(double c1, double c2, out string reason) { reason = string.Empty; return true; } public virtual void SetPower(float power) { } public virtual void SetPulseMode(bool on) { } public virtual void SetPulseRateFreq(int nFreq) { } public virtual void SetPulseDutyCycle(int percentage) { } public virtual void Terminate() { } public virtual void Monitor() { if (_scCalibrationTable != null) { if (string.IsNullOrEmpty(_previousSetting) || _previousSetting != _scCalibrationTable.StringValue) UpdateCalibrationTable(); } } public virtual void Reset() { _alarmChecker.RST = true; _warningChecker.RST = true; _recipeWarningChecker.RST = true; _recipeAlarmChecker.RST = true; } public virtual void SetCommunicationMode(int mode) { } protected virtual void UpdateCalibrationTable() { if (_scCalibrationTable == null) return; if (_previousSetting == _scCalibrationTable.StringValue) return; _previousSetting = _scCalibrationTable.StringValue; if (string.IsNullOrEmpty(_previousSetting)) { _calibrationTable = new List(); return; } var table = new List>(); string[] items = _previousSetting.Split(';'); for (int i = 0; i < items.Length; i++) { string itemValue = items[i]; if (!string.IsNullOrEmpty(itemValue)) { string[] pairValue = itemValue.Split('#'); if (pairValue.Length == 2) { if (float.TryParse(pairValue[0], out float rawData) && float.TryParse(pairValue[1], out float calibrationData)) { table.Add(Tuple.Create(rawData, calibrationData)); } } } } table = table.OrderBy(x => x.Item1).ToList(); var calibrationTable = new List(); for (int i = 0; i < table.Count; i++) { if (i == 0 && table[0].Item1 > 0.001) { calibrationTable.Add(new CalibrationItem() { RawFrom = 0, CalibrationFrom = 0, RawTo = table[0].Item1, CalibrationTo = table[0].Item2, }); } if (i == table.Count - 1) { float maxValue = (float)ScalePower; calibrationTable.Add(new CalibrationItem() { RawFrom = table[i].Item1, RawTo = table[i].Item2, CalibrationFrom = maxValue, CalibrationTo = maxValue, }); continue; } calibrationTable.Add(new CalibrationItem() { RawFrom = table[i].Item1, CalibrationFrom = table[i].Item2, RawTo = table[i + 1].Item1, CalibrationTo = table[i + 1].Item2, }); } _calibrationTable = calibrationTable; } protected virtual float CalibrationData(float value, bool output) { //default enable if (_scEnableCalibration != null && !_scEnableCalibration.BoolValue) return value; if (_scCalibrationTable == null || !_calibrationTable.Any()) return value; float ret = value; if (output) { var item = _calibrationTable.FirstOrDefault(x => x.RawFrom <= value && x.RawTo >= value); if (item != null && Math.Abs(item.RawTo - item.RawFrom) > 0.01) { var slope = (item.CalibrationTo - item.CalibrationFrom) / (item.RawTo - item.RawFrom); ret = (ret - item.RawFrom) * slope + item.CalibrationFrom; } } else { var item = _calibrationTable.FirstOrDefault(x => x.CalibrationFrom <= value && x.CalibrationTo >= value); if(item != null && item.CalibrationTo == 0 && item.CalibrationFrom == 0 && value > 0) item = _calibrationTable[_calibrationTable.Count - 1]; if (item != null && Math.Abs(item.CalibrationTo - item.CalibrationFrom) > 0.01) { var slope = (item.RawTo - item.RawFrom) / (item.CalibrationTo - item.CalibrationFrom); ret = (ret - item.CalibrationFrom) * slope + item.RawFrom; } } if (ret < 0) return 0; if (ret >= float.MaxValue || ret > ScalePower) ret = value; return ret; } public virtual bool ReConnect() { return true; } } }