using CapMachine.Wpf.Services;
using Prism.Events;
using Prism.Mvvm;
using Stateless;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace CapMachine.Wpf.Models
{
///
/// 设备的运行状态
/// https://www.cnblogs.com/podolski/p/13215064.html
///
public class MachineRunState : BindableBase
{
///
/// 实例化
///
public MachineRunState(string name, IEventAggregator eventAggregator, ConfigService configService, CanDriveService canDriveService, LinDriveService linDriveService)
{
Name = name;
EventAggregator = eventAggregator;
ConfigService = configService;
InitConfig();
}
private string _RunStateMsg = "等待";
///
/// 运行状态
///
public string RunStateMsg
{
get { return _RunStateMsg; }
set { _RunStateMsg = value; RaisePropertyChanged(); }
}
private bool _IsRunState;
///
/// 是否运行状态
///
public bool IsRunState
{
get { return _IsRunState; }
set { _IsRunState = value; RaisePropertyChanged(); }
}
private bool _IsProLoad;
///
/// PLC程序是否下载
///
public bool IsProLoad
{
get { return _IsProLoad; }
set { _IsProLoad = value; RaisePropertyChanged(); }
}
///
/// 状态机
///
public StateMachine StateMachine { get; set; }
///
/// 初始化配置信息
///
private void InitConfig()
{
//未配置触发器 CanFire 返回值 false
//状态机初始化
StateMachine = new StateMachine(RunState.Wait);
StateMachine.Configure(RunState.Wait)
.OnEntry(t => WaitEntryCall())
.OnExit(t => WaitExitCall())
.PermitIf(RunStateTrig.AlarmTrig, RunState.Alarm, () => AlarmPreValid())
.PermitIf(RunStateTrig.StartTrig, RunState.Run, () => RunPreValid())
//.Permit(RunStateTrig.StartTrig, RunState.Run)
.PermitIf(RunStateTrig.ResetTrig, RunState.Stop, () => StopPreValid());
//.PermitIf(RunStateTrig.EndTrig, RunState.Stop, () => StopPreValid())
//.PermitIf(RunStateTrig.PauseTrig, RunState.Pause, () => PausePreValid())
//.Ignore(RunStateTrig.ResetTrig);
//.Ignore(RunStateTrig.ContinueTrig)
//.Ignore(RunStateTrig.WaitTrig);
StateMachine.Configure(RunState.Alarm)
.OnEntry(t => AlarmEntryCall())
.OnExit(t => AlarmExitCall())
.PermitIf(RunStateTrig.WaitTrig, RunState.Wait, () => WaitPreValid())
.PermitIf(RunStateTrig.ResetTrig, RunState.Stop, () => StopPreValid());
//.PermitIf(RunStateTrig.StartTrig, RunState.Run, () => RunPreValid())
//.PermitIf(RunStateTrig.EndTrig, RunState.Stop, () => StopPreValid())
//.PermitIf(RunStateTrig.PauseTrig, RunState.Pause, () => PausePreValid())
//.Ignore(RunStateTrig.ContinueTrig)
//.Ignore(RunStateTrig.AlarmTrig);
StateMachine.Configure(RunState.Run)
.OnEntry(t => RunEntryCall())
.OnExit(t => RunExitCall())
//.PermitIf(RunStateTrig.WaitTrig, RunState.Wait, () => WaitPreValid())
.PermitIf(RunStateTrig.ResetTrig, RunState.Stop, () => StopPreValid())
.PermitIf(RunStateTrig.AlarmTrig, RunState.Alarm, () => AlarmPreValid())
.PermitIf(RunStateTrig.EndTrig, RunState.Stop, () => StopPreValid())
.PermitIf(RunStateTrig.PauseTrig, RunState.Pause, () => PausePreValid());
//.PermitIf(RunStateTrig.ContinueTrig, RunState.Stop, () => false)
//.Ignore(RunStateTrig.ContinueTrig)
//.Ignore(RunStateTrig.StartTrig);
StateMachine.Configure(RunState.Stop)
.OnEntry(t => StopEntryCall())
.OnExit(t => StopExitCall())
.PermitIf(RunStateTrig.WaitTrig, RunState.Wait, () => WaitPreValid())
.PermitIf(RunStateTrig.AlarmTrig, RunState.Alarm, () => AlarmPreValid())
.PermitIf(RunStateTrig.StartTrig, RunState.Run, () => RunPreValid());
//.PermitIf(RunStateTrig.PauseTrig, RunState.Pause, () => PausePreValid())
//.Ignore(RunStateTrig.ContinueTrig)
//.Ignore(RunStateTrig.PauseTrig)
//.Ignore(RunStateTrig.EndTrig);
StateMachine.Configure(RunState.Pause)
.OnEntry(t => PauseEntryCall())
.OnExit(t => PauseExitCall())
.Permit(RunStateTrig.ContinueTrig, RunState.Run)
//.PermitIf(RunStateTrig.WaitTrig, RunState.Wait, () => WaitPreValid())
.PermitIf(RunStateTrig.ResetTrig, RunState.Stop, () => StopPreValid())
.PermitIf(RunStateTrig.AlarmTrig, RunState.Alarm, () => AlarmPreValid())
//.PermitIf(RunStateTrig.StartTrig, RunState.Run, () => RunPreValid())
.Permit(RunStateTrig.EndTrig, RunState.Stop);
//.Ignore(RunStateTrig.PauseTrig);
}
private bool _BtnStartState;
///
/// 界面的开始按钮状态
///
public bool BtnStartState
{
get { return _BtnStartState; }
set { _BtnStartState = value; RaisePropertyChanged(); }
}
private bool _BtnEndState;
///
/// 界面的结束按钮状态
///
public bool BtnEndState
{
get { return _BtnEndState; }
set { _BtnEndState = value; RaisePropertyChanged(); }
}
#region 验证状态
///
/// 进入 Wait 状态
///
///
public bool FireWait()
{
var Result = StateMachine.CanFire(RunStateTrig.WaitTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.WaitTrig);
return true;
}
else
{
MessageBox.Show($"WaitTrig-没有满足Wait条件");
return false;
}
}
///
/// 进入 Alarm状态
///
///
public bool FireAlarm()
{
StateMachine.Fire(RunStateTrig.AlarmTrig);
return true;
//var Result = StateMachine.CanFire(RunStateTrig.AlarmTrig);
//if (Result)
//{
// StateMachine.Fire(RunStateTrig.AlarmTrig);
// return true;
//}
//else
//{
// MessageBox.Show($"AlarmTrig-没有满足条件");
// return false;
//}
}
///
/// 进入 Reset状态
///
///
public bool FireReset()
{
var Result = StateMachine.CanFire(RunStateTrig.ResetTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.ResetTrig);
return true;
}
else
{
MessageBox.Show($"ResetTrig-没有满足Reset条件");
return false;
}
}
///
/// 进入 Start 状态
///
///
public bool FireStart()
{
var Result = StateMachine.CanFire(RunStateTrig.StartTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.StartTrig);
return true;
}
else
{
MessageBox.Show($"StartTrig-没有满足Start条件");
return false;
}
}
///
/// 进入 End 状态
///
///
public bool FireEnd()
{
var Result = StateMachine.CanFire(RunStateTrig.EndTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.EndTrig);
return true;
}
else
{
MessageBox.Show($"EndTrig-没有满足End条件");
return false;
}
}
///
/// 进入 Pause 状态
///
///
public bool FirePause()
{
var Result = StateMachine.CanFire(RunStateTrig.PauseTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.PauseTrig);
return true;
}
else
{
MessageBox.Show($"PauseTrig-没有满足Pause条件");
return false;
}
}
///
/// 进入 Continue 状态
///
///
public bool FireContinue()
{
var Result = StateMachine.CanFire(RunStateTrig.ContinueTrig);
if (Result)
{
StateMachine.Fire(RunStateTrig.ContinueTrig);
return true;
}
else
{
MessageBox.Show($"ContinueTrig-没有满足Continue条件");
return false;
}
}
///
/// 运行 状态的条件判断验证
///
///
///
private bool RunPreValid()
{
if (ConfigService.IsExpInfoOk && IsProLoad)
{
//程序下载并且,试验信息已经设置好后,就可以开始了
return true;
}
return false;
}
///
///进入 报警 状态的条件判断验证
///
///
///
private bool AlarmPreValid()
{
return true;
}
///
///进入 等待 状态的条件判断验证
///
///
///
private bool WaitPreValid()
{
return true;
}
///
///进入 停止 状态的条件判断验证
///
///
///
private bool StopPreValid()
{
return true;
////运行切换到停止
//if (StateMachine.State == RunState.Run)
//{
// return true;
//}
//return false;
}
///
///进入 暂停 状态的条件判断验证
///
///
///
private bool PausePreValid()
{
//运行切换到停止
if (StateMachine.State == RunState.Run)
{
return true;
}
return false;
}
#endregion
#region 状态离开和进入方法
private void PauseExitCall()
{
Console.WriteLine($"{Name}-PauseExitCall");
}
private void PauseEntryCall()
{
RunStateMsg = "暂停";
Console.WriteLine($"{Name}-PauseEntryCall");
}
private void StopExitCall()
{
BtnEndState = false;
Console.WriteLine($"{Name}-StopExitCall");
}
///
/// 进入停止状态
///
private void StopEntryCall()
{
BtnEndState = true;
RunStateMsg = "停止";
Console.WriteLine($"{Name}-StopEntryCall");
}
private void RunExitCall()
{
BtnStartState = false;
//退出运行状态
IsRunState = false;
Console.WriteLine($"{Name}-RunExitCall");
}
///
/// 进入运行状态
///
private void RunEntryCall()
{
BtnStartState = true;
RunStateMsg = "运行";
Console.WriteLine($"{Name}-RunEntryCall");
//进入运行状态
IsRunState = true;
}
private void AlarmExitCall()
{
Console.WriteLine($"{Name}-AlarmExitCall");
}
private void AlarmEntryCall()
{
RunStateMsg = "报警";
Console.WriteLine($"{Name}-AlarmEntryCall");
}
///
/// 离开 等待
///
///
private void WaitExitCall()
{
Console.WriteLine($"{Name}-WaitExitCall");
}
///
/// 进入 等待
///
private void WaitEntryCall()
{
RunStateMsg = "等待";
Console.WriteLine($"{Name}-WaitExitCall");
}
#endregion
///
/// 设备名称
///
public string Name { get; set; }
public IEventAggregator EventAggregator { get; }
public ConfigService ConfigService { get; }
public CanDriveService CanDriveService { get; }
public LinDriveService LinDriveService { get; }
}
}