add recipe function to FSM

master
syneffort 11 months ago
parent 37e3db04c9
commit 0d42f94fb4
  1. 1
      DesignPattern/FSM/FSM.csproj
  2. 16
      DesignPattern/FSM/Program.cs
  3. 47
      DesignPattern/FSM/Recipes/Recipe.cs
  4. 18
      DesignPattern/FSM/States/IdleState.cs
  5. 10
      DesignPattern/FSM/States/PausedState.cs
  6. 46
      DesignPattern/FSM/States/RunningState.cs

@ -44,6 +44,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Machines\EquipmentEvent.cs" /> <Compile Include="Machines\EquipmentEvent.cs" />
<Compile Include="Machines\EquipmentStateMachine.cs" /> <Compile Include="Machines\EquipmentStateMachine.cs" />
<Compile Include="Recipes\Recipe.cs" />
<Compile Include="States\EmergencyStoppedState.cs" /> <Compile Include="States\EmergencyStoppedState.cs" />
<Compile Include="States\IdleState.cs" /> <Compile Include="States\IdleState.cs" />
<Compile Include="States\IEquipmentState.cs" /> <Compile Include="States\IEquipmentState.cs" />

@ -1,4 +1,5 @@
using FSM.Machines; using FSM.Machines;
using FSM.Recipes;
using FSM.States; using FSM.States;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -15,7 +16,18 @@ namespace FSM
{ {
PrintMessage("********** Start of the program **********"); PrintMessage("********** Start of the program **********");
IEquipmentState initialState = new IdleState(); IdleState initialState = new IdleState();
Recipe recipe = new Recipe("Main recipe",
new List<string>()
{
"MainRecipe_Step1",
"MainRecipe_Step2",
"MainRecipe_Step3",
"MainRecipe_Step4",
"MainRecipe_Step5",
});
initialState.SetRecipe(recipe);
var machine = new EquipmentStateMachine(initialState); var machine = new EquipmentStateMachine(initialState);
machine.OnHandleEvent -= machine_OnHandleEvent; machine.OnHandleEvent -= machine_OnHandleEvent;
machine.OnHandleEvent += machine_OnHandleEvent; machine.OnHandleEvent += machine_OnHandleEvent;
@ -37,7 +49,7 @@ namespace FSM
foreach (EquipmentEvent evt in eventCommands) foreach (EquipmentEvent evt in eventCommands)
{ {
machine.HandleEvent(evt); machine.HandleEvent(evt);
Thread.Sleep(1000); Thread.Sleep(10 * 1000);
} }
PrintMessage("********** End of the program **********" + Environment.NewLine); PrintMessage("********** End of the program **********" + Environment.NewLine);

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSM.Recipes
{
class Recipe
{
public string Name { get; private set; }
public List<string> Steps { get; private set; }
private int _currentStepIndex;
public int CurrentStepIndex { get { return _currentStepIndex; } }
public Recipe(string name, List<string> steps)
{
Name = name;
Steps = steps;
_currentStepIndex = 0;
}
public void Reset()
{
_currentStepIndex = 0;
}
public string GetCurrentStep()
{
if (_currentStepIndex < Steps.Count)
return Steps[_currentStepIndex];
return null;
}
public bool MoveToNextStep()
{
if (_currentStepIndex < Steps.Count - 1)
{
_currentStepIndex++;
return true;
}
return false;
}
}
}

@ -1,4 +1,5 @@
using FSM.Machines; using FSM.Machines;
using FSM.Recipes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -9,6 +10,8 @@ namespace FSM.States
{ {
class IdleState : IEquipmentState class IdleState : IEquipmentState
{ {
private Recipe _currentRecipe;
public void Enter() public void Enter()
{ {
Console.WriteLine("Entering IdleState"); Console.WriteLine("Entering IdleState");
@ -19,13 +22,24 @@ namespace FSM.States
Console.WriteLine("Exiting IdleState"); Console.WriteLine("Exiting IdleState");
} }
public void SetRecipe(Recipe recipe)
{
_currentRecipe = recipe;
Console.WriteLine(string.Format("Recipe {0} set in IdleState", _currentRecipe.Name));
}
public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine) public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine)
{ {
switch (equipmentEvent) switch (equipmentEvent)
{ {
case EquipmentEvent.Start: case EquipmentEvent.Start:
machine.SetState(new RunningState()); if (_currentRecipe != null)
return true; {
machine.SetState(new RunningState(_currentRecipe));
return true;
}
Console.WriteLine("No recipe set. Unable to start.");
return false;
case EquipmentEvent.EmergencyStop: case EquipmentEvent.EmergencyStop:
machine.SetState(new EmergencyStoppedState()); machine.SetState(new EmergencyStoppedState());
return true; return true;

@ -1,4 +1,5 @@
using FSM.Machines; using FSM.Machines;
using FSM.Recipes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -9,6 +10,13 @@ namespace FSM.States
{ {
class PausedState : IEquipmentState class PausedState : IEquipmentState
{ {
private Recipe _currentRecipe;
public PausedState(Recipe recipe)
{
_currentRecipe = recipe;
}
public void Enter() public void Enter()
{ {
Console.WriteLine("Entering PausedState"); Console.WriteLine("Entering PausedState");
@ -24,7 +32,7 @@ namespace FSM.States
switch (equipmentEvent) switch (equipmentEvent)
{ {
case EquipmentEvent.Resume: case EquipmentEvent.Resume:
machine.SetState(new RunningState()); machine.SetState(new RunningState(_currentRecipe));
return true; return true;
case EquipmentEvent.Stop: case EquipmentEvent.Stop:
machine.SetState(new IdleState()); machine.SetState(new IdleState());

@ -1,22 +1,38 @@
using FSM.Machines; using FSM.Machines;
using FSM.Recipes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers;
namespace FSM.States namespace FSM.States
{ {
class RunningState : IEquipmentState class RunningState : IEquipmentState
{ {
private Recipe _currentRecipe;
private Timer _timer;
public RunningState(Recipe recipe)
{
_currentRecipe = recipe;
_timer = new Timer(3000);
_timer.Elapsed += OnTimedEvent;
}
public void Enter() public void Enter()
{ {
Console.WriteLine("Entering RunningState"); Console.WriteLine(string.Format("Entering RunningState with recipe: {0}", _currentRecipe.Name));
ExecuteCurrentStep();
_timer.Start();
} }
public void Exit() public void Exit()
{ {
Console.WriteLine("Exiting RunningState"); Console.WriteLine("Exiting RunningState");
_timer.Stop();
} }
public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine) public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine)
@ -24,7 +40,7 @@ namespace FSM.States
switch (equipmentEvent) switch (equipmentEvent)
{ {
case EquipmentEvent.Pause: case EquipmentEvent.Pause:
machine.SetState(new PausedState()); machine.SetState(new PausedState(_currentRecipe));
return true; return true;
case EquipmentEvent.Stop: case EquipmentEvent.Stop:
machine.SetState(new IdleState()); machine.SetState(new IdleState());
@ -36,5 +52,31 @@ namespace FSM.States
return false; return false;
} }
} }
private void ExecuteCurrentStep()
{
var step = _currentRecipe.GetCurrentStep();
if (string.IsNullOrEmpty(step))
{
Console.WriteLine("Recipe completed");
}
else
{
Console.WriteLine(string.Format("Execute step {0}: {1}", _currentRecipe.CurrentStepIndex + 1, step));
}
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
if (_currentRecipe.MoveToNextStep())
{
ExecuteCurrentStep();
}
else
{
Console.WriteLine("Recipe completed");
_timer.Stop();
}
}
} }
} }

Loading…
Cancel
Save