using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using System.Windows.Input; using System.Windows.Threading; using MECF.Framework.Common.OperationCenter; using Prism.Mvvm; using Prism.Commands; using MECF.Framework.Common.CommonData.SRD; using MECF.Framework.Common.Persistent.SRD; using MECF.Framework.Common.CommonData.PUF; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Utilities; using MECF.Framework.Common.RecipeCenter; using System.Collections.ObjectModel; using CyberX8_MainPages.PMs; using MECF.Framework.Common.Beckhoff.Station; using CyberX8_MainPages.Unity; using WaferInfo = OpenSEMI.ClientBase.WaferInfo; namespace CyberX8_MainPages.ViewModels { internal class SRDHomePageViewModel:BindableBase { #region 常量 private const string COMMON_DATA = "CommonData"; private const string PERSISTENT_VALUE = "PersistentValue"; private const string WAFER_PRESENCE_STATUS = "WaferPresenceStatus"; private const string SRD = "srd"; private const string WAFER_HOLDER= "WaferHolder"; private const string LOADER_DI_ENABLE = "LoaderDiEnable"; private const string FACILITIES = "Facilities"; private const string MOTION_DATA = "MotionData"; private const double ARM_UI_HOME_POSITION = 25.682; private const double ARM_UI_CENTER_POSITION = -15; private const double ROTATION_UI_HOME_POSITION = 0; #endregion #region 内部变量 #region SRD /// <summary> /// SRDRecipeContent /// </summary> private string _recipeContent; /// <summary> /// TimeRemaining /// </summary> private double _timeRemaining; /// <summary> /// OfTotalTime /// </summary> private double _totalTime; /// <summary> /// OperatingMode /// </summary> private string _operatingMode; /// <summary> /// State /// </summary> private string _state; /// <summary> /// RecipeMode /// </summary> private string _recipeMode; /// <summary> /// AchievedRunRecipeCycle /// </summary> private int _achievedRunRecipeCycle; /// <summary> /// Loader DI /// </summary> private bool _loaderDiEnable; #endregion #region wafer /// <summary> /// WaferID /// </summary> private string _waferID = ""; /// <summary> /// SeqRecipe /// </summary> private string _seqRecipe; /// <summary> /// Wafer信息 /// </summary> private WaferInfo _waferInfo; #endregion #region SRD recipe /// <summary> /// RecipeModuleName /// </summary> private string _recipeModuleName; /// <summary> /// RecipeType /// </summary> private string _recipeType; /// <summary> /// 当前选择Recipe节点 /// </summary> private RecipeNode _selectedRecipeNode; /// <summary> /// Recipe节点 /// </summary> private ObservableCollection<RecipeNode> _recipeNodes; // <summary> /// 当前Recipe /// </summary> private string _currentRecipe; #endregion #region Common /// <summary> /// 模块名称 /// </summary> private string _module; /// <summary> /// State Machine /// </summary> private string _stateMachine; /// <summary> /// Status /// </summary> private string _status; /// <summary> /// 数据 /// </summary> private SrdCommonData _sRDCommonData; /// <summary> /// Threshold /// </summary> private SRDPersistentValue _sRDPersistent; /// <summary> /// WaferPresence /// </summary> private string _waferPresence; /// <summary> /// PresenceTest是否进行中 /// </summary> private bool _isPresenceTesting; /// <summary> /// Test Without Wafers /// </summary> private bool _isWaferPresence; /// <summary> /// sRDArm运动数据 /// </summary> private CommandMotionData _sRDArmMotionData; /// <summary> /// sRDRotation运动数据 /// </summary> private CommandMotionData _sRDRotationMotionData; /// <summary> /// 页面功能启用 /// </summary> private bool _isEnabled; /// <summary> /// AutoMode页面功能启用 /// </summary> private bool _isAutoEnabled; #endregion #region 系统数据 /// <summary> /// 定时器 /// </summary> DispatcherTimer _timer; /// <summary> /// 查询后台数据集合 /// </summary> private List<string> _rtDataKeys = new List<string>(); /// <summary> /// rt查询key数值字典 /// </summary> private Dictionary<string, object> _rtDataValueDic = new Dictionary<string, object>(); /// <summary> /// UiRecipeManager /// </summary> private UiRecipeManager _uiRecipeManager = new UiRecipeManager(); #endregion #region UI related /// <summary> /// SRD Arm UI位置 /// </summary> private double _srdArmUIPosition = ARM_UI_HOME_POSITION; /// <summary> /// SRD Rotation UI位置 /// </summary> private double _srdRotationUIPosition = ROTATION_UI_HOME_POSITION; /// <summary> /// Arm Axis位置数据 /// </summary> private BeckhoffStationAxis _armAxis; /// <summary> /// Arm UI位置比例 /// </summary> private double _armUIRatio; #endregion #endregion #region 属性 #region SRD /// <summary> /// SRDRecipeContent /// </summary> public string SRDRecipeContent { get { return _recipeContent; } set { SetProperty(ref _recipeContent, value); } } /// <summary> /// TimeRemaining /// </summary> public double TimeRemaining { get { return _timeRemaining; } set { SetProperty(ref _timeRemaining, value); } } /// <summary> /// TotalTime /// </summary> public double TotalTime { get { return _totalTime; } set { SetProperty(ref _totalTime, value); } } /// <summary> /// OperatingMode /// </summary> public string OperatingMode { get { return _operatingMode; } set { SetProperty(ref _operatingMode, value); } } /// <summary> /// State /// </summary> public string State { get { return _state; } set { SetProperty(ref _state, value); } } /// <summary> /// RecipeMode /// </summary> public string RecipeMode { get { return _recipeMode; } set { SetProperty(ref _recipeMode, value); } } /// <summary> /// Run Recipe已经完成的次数 /// </summary> public int AchievedRunRecipeCycle { get { return _achievedRunRecipeCycle; } set { SetProperty(ref _achievedRunRecipeCycle, value); } } /// <summary> /// Loader DI /// </summary> public bool LoaderDiEnable { get { return _loaderDiEnable; } set { SetProperty(ref _loaderDiEnable, value); } } #endregion #region wafer /// <summary> /// WaferID /// </summary> public string WaferID { get { return _waferID; } set { SetProperty(ref _waferID, value); } } /// <summary> /// SeqRecipe /// </summary> public string SeqRecipe { get { return _seqRecipe; } set { SetProperty(ref _seqRecipe, value); } } /// <summary> /// Wafer信息 /// </summary> public WaferInfo WaferInfo { get { return _waferInfo; } set { SetProperty(ref _waferInfo, value); } } #endregion #region SRD recipe /// <summary> /// RecipeModuleName /// </summary> public string RecipeModuleName { get { return _recipeModuleName; } set { SetProperty(ref _recipeModuleName, value); } } /// <summary> /// RecipeType /// </summary> public string RecipeType { get { return _recipeType; } set { SetProperty(ref _recipeType, value); } } /// <summary> /// 当前运行的Recipe /// </summary> public string CurrentRecipe { get { return _currentRecipe; } set { SetProperty(ref _currentRecipe, value); } } #endregion #region Common /// <summary> /// 模块名称 /// </summary> public string Module { get { return _module; } set { SetProperty(ref _module, value); } } /// <summary> /// StateMachine /// </summary> public string StateMachine { get { return _stateMachine; } set { SetProperty(ref _stateMachine, value); } } /// <summary> /// StateMachine /// </summary> public string Status { get { return _status; } set { SetProperty(ref _status, value); } } /// <summary> /// Commondata /// </summary> public SrdCommonData SRDCommonData { get { return _sRDCommonData; } set { SetProperty(ref _sRDCommonData, value); } } /// <summary> /// WaferPresence /// </summary> public string WaferPresence { get { return _waferPresence; } set { SetProperty(ref _waferPresence, value); } } /// <summary> /// Threshold /// </summary> public SRDPersistentValue SRDPersistent { get { return _sRDPersistent; } set { SetProperty(ref _sRDPersistent, value); } } /// <summary> /// Selected Recipe Node /// </summary> public RecipeNode SelectedRecipeNode { get { return _selectedRecipeNode; } set { SetProperty(ref _selectedRecipeNode, value); } } /// <summary> /// PresenceTest是否进行中 /// </summary> public bool IsPresenceTesting { get { return _isPresenceTesting; } set { SetProperty(ref _isPresenceTesting, value); } } /// <summary> /// Test Without Wafers /// </summary> public bool IsWaferPresence { get { return _isWaferPresence; } set { SetProperty(ref _isWaferPresence, value); } } /// <summary> /// SRDArm运动数据 /// </summary> public CommandMotionData SRDArmMotionData { get { return _sRDArmMotionData; } set { SetProperty(ref _sRDArmMotionData, value); } } /// <summary> /// SRDRotation运动数据 /// </summary> public CommandMotionData SRDRotationMotionData { get { return _sRDRotationMotionData; } set { SetProperty(ref _sRDRotationMotionData, value); } } /// <summary> /// 页面功能启用 /// </summary> public bool IsEnabled { get { return _isEnabled; } set { SetProperty(ref _isEnabled, value); } } /// <summary> /// AutoMode页面功能启用 /// </summary> public bool IsAutoEnabled { get { return _isAutoEnabled; } set { SetProperty(ref _isAutoEnabled, value); } } #endregion #region UI related /// <summary> /// SRD ARM UI位置 /// </summary> public double SRDArmUIPosition { get { return _srdArmUIPosition; } set { SetProperty(ref _srdArmUIPosition, value); } } /// <summary> /// SRD Rotation UI位置 /// </summary> public double SRDRotationUIPosition { get { return _srdRotationUIPosition; } set { SetProperty(ref _srdRotationUIPosition, value); } } #endregion #endregion #region Command指令 /// <summary> /// Initialize Command /// </summary> public ICommand InitializeCommand { get; set; } /// <summary> /// SwitchOn Command /// </summary> public ICommand SwitchOnCommand { get; set; } /// <summary> /// SwitchOff Command /// </summary> public ICommand SwitchOffCommand { get; set; } /// <summary> /// Loader Command /// </summary> public ICommand LoaderCommand { get; set; } /// <summary> /// Unloader Command /// </summary> public ICommand UnloaderCommand { get; set; } #endregion /// <summary> /// 构造函数 /// </summary> public SRDHomePageViewModel() { InitializeCommand = new DelegateCommand<object>(InitializeAction); SwitchOnCommand = new DelegateCommand<object>(SwitchOnAction); SwitchOffCommand = new DelegateCommand<object>(SwitchOffAction); LoaderCommand = new DelegateCommand<object>(LoaderAction); UnloaderCommand = new DelegateCommand<object>(UnloaderAction); } /// <summary> /// 加载数据 /// </summary> public void LoadData(string systemName) { Module = systemName; RecipeType = "srd"; RecipeModuleName = "SRD Recipe"; _rtDataKeys.Clear(); _rtDataKeys.Add($"{Module}.IsHomed"); _rtDataKeys.Add($"{Module}.{COMMON_DATA}"); _rtDataKeys.Add($"{Module}.{PERSISTENT_VALUE}"); _rtDataKeys.Add($"{Module}.{WAFER_PRESENCE_STATUS}"); _rtDataKeys.Add($"{Module}.AchievedCycle"); _rtDataKeys.Add($"{Module}.FsmState"); _rtDataKeys.Add($"{Module}.CurrentStateMachine"); _rtDataKeys.Add($"{Module}.CurrentStatus"); _rtDataKeys.Add($"{Module}.WaferInfo"); _rtDataKeys.Add($"{Module}.IsPresenceTesting"); _rtDataKeys.Add($"{Module}.IsWaferPresence"); _rtDataKeys.Add($"System.{FACILITIES}.{LOADER_DI_ENABLE}"); _rtDataKeys.Add($"{Module}.Arm.{MOTION_DATA}"); _rtDataKeys.Add($"{Module}.Rotation.{MOTION_DATA}"); _rtDataKeys.Add($"Station.{Module}.Arm"); _rtDataKeys.Add($"{Module}.CurrentRecipe"); _rtDataKeys.Add($"{Module}.TotalTime"); _rtDataKeys.Add($"{Module}.TimeRemain"); if (_timer == null) { _timer = new DispatcherTimer(); _timer.Interval = TimeSpan.FromMilliseconds(200); _timer.Tick += Timer_Tick; } _timer.Start(); _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys); if (_rtDataValueDic != null) { _armAxis = CommonFunction.GetValue<BeckhoffStationAxis>(_rtDataValueDic, $"Station.{Module}.Arm"); //计算Arm位置比例 if (_armAxis != null) { double armHomePos = double.Parse(_armAxis.Stations[0].Position); double armCenterPos = double.Parse(_armAxis.Stations[1].Position); _armUIRatio = (ARM_UI_HOME_POSITION - ARM_UI_CENTER_POSITION) / (armHomePos - armCenterPos); } } } /// <summary> /// 定时器执行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Timer_Tick(object sender, EventArgs e) { if (_rtDataKeys.Count != 0) { _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys); if (_rtDataValueDic != null) { SRDCommonData = CommonFunction.GetValue<SrdCommonData>(_rtDataValueDic, $"{Module}.{COMMON_DATA}"); SRDPersistent = CommonFunction.GetValue<SRDPersistentValue>(_rtDataValueDic, $"{Module}.{PERSISTENT_VALUE}"); LoaderDiEnable = CommonFunction.GetValue<bool>(_rtDataValueDic, $"System.{FACILITIES}.{LOADER_DI_ENABLE}"); AchievedRunRecipeCycle = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.AchievedCycle"); WaferPresence = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.{WAFER_PRESENCE_STATUS}"); State = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.FsmState"); CurrentRecipe = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentRecipe"); IsWaferPresence = CommonFunction.GetValue<bool>(_rtDataValueDic, $"{Module}.IsWaferPresence"); if (SRDPersistent != null) { if ("Manual".Equals(SRDPersistent.OperatingMode)) { IsEnabled = true; IsAutoEnabled = true; } else if ("Auto".Equals(SRDPersistent.OperatingMode)) { if (!IsWaferPresence) { InvokeClient.Instance.Service.DoOperation($"{Module}.UpdateIsWaferPresenceAction", true); } IsAutoEnabled = true; IsEnabled = false; } else { State = "Stopped"; IsEnabled = false; IsAutoEnabled = false; } } StateMachine = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentStateMachine"); Status = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentStatus"); IsPresenceTesting = CommonFunction.GetValue<bool>(_rtDataValueDic, $"{Module}.IsPresenceTesting"); SRDArmMotionData = CommonFunction.GetValue<CommandMotionData>(_rtDataValueDic, $"{Module}.Arm.{MOTION_DATA}"); SRDRotationMotionData = CommonFunction.GetValue<CommandMotionData>(_rtDataValueDic, $"{Module}.Rotation.{MOTION_DATA}"); //SRD Wafer信息 if (ModuleManager.ModuleInfos[Module].WaferManager.Wafers.Count != 0) { WaferInfo = ModuleManager.ModuleInfos[Module].WaferManager.Wafers[0]; } //计算ARM UI位置 if (SRDArmMotionData != null) { SRDArmUIPosition = ARM_UI_HOME_POSITION + _armUIRatio * SRDArmMotionData.MotorPosition; } //计算Rotation UI位置 if (SRDRotationMotionData != null) { SRDRotationUIPosition = SRDRotationMotionData.MotorPosition; } TotalTime = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.TotalTime"); TimeRemaining = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.TimeRemain"); if (State == "Idle") { TimeRemaining = 0; } } } } /// <summary> /// 隐藏 /// </summary> public void Hide() { if (_timer != null) { _timer.Stop(); } } #region 指令Action /// <summary> /// Home Action /// </summary> /// <param name="param"></param> private void HomeAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.HomeAll"); } /// <summary> /// Initialize Action /// </summary> /// <param name="param"></param> private void InitializeAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.InitializeHome"); } /// <summary> /// Switch On Action /// </summary> /// <param name="param"></param> private void SwitchOnAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.SwitchOnAll"); } /// <summary> /// Switch Off Action /// </summary> /// <param name="param"></param> private void SwitchOffAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.SwitchOffAll"); } /// <summary> /// Loader Action /// </summary> /// <param name="param"></param> private void LoaderAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.Loader"); } /// <summary> /// Unloader Action /// </summary> /// <param name="param"></param> private void UnloaderAction(object param) { InvokeClient.Instance.Service.DoOperation($"{Module}.Unloader"); } #endregion } }