Inhalte

Dependency Injection: Stopper Workflows

Table of Contents

Introduction

We have already defined the interfaces for a status and for a workflow status. We can use these to build state machines later. Now we build the individual states for the two workflows, send and receive.

Abstract Workflow State

Abstract Class AbstractWorkflowState
FUNCTION_BLOCK ABSTRACT AbstractWorkflowState IMPLEMENTS IWorkfowState
VAR
	nextState 		:IStatemachine;
END_VAR
METHOD ABSTRACT executeState :IStatemachine
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	nextState :IStatemachine;
END_VAR
THIS^.nextState := nextState;
METHOD setNextState
VAR_INPUT
	nextState	: IStatemachine;
END_VAR
THIS^.nextState := nextState;

Receiving Workflow

Class StateReceivingWorkflow
FUNCTION_BLOCK StateReceivingWorkflow EXTENDS AbstractWorkflowState
VAR
	cylinder :ICylinder;
	jamSensor :IDigitalSensor;
	transportInterface :ITransportInterfaceForReceiver;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	cylinder :ICylinder;
	jamSensor :IDigitalSensor;
	transportInterface :ITransportInterfaceForReceiver;
END_VAR
THIS^.cylinder := cylinder;
THIS^.jamSensor := jamSensor;
THIS^.transportInterface := transportInterface;
METHOD executeState :IStatemachine
VAR
	read2Receive	:BOOL;
	partReceived	:BOOL;
END_VAR
read2Receive := (THIS^.cylinder.isAtHomePosition);
partReceived := (THIS^.jamSensor.isOccupied);
executeState := THIS^;

IF (read2Receive AND (NOT partReceived)) THEN
	THIS^.transportInterface.resetPartIsArrived();
	THIS^.transportInterface.setIAmReadyToReceive();
ELSIF (partReceived) THEN
	THIS^.transportInterface.resetIAmReadyToReceive();
	THIS^.transportInterface.setPartIsArrived();
	executeState := THIS^.nextState;
ELSE
	THIS^.transportInterface.resetIAmReadyToReceive();
END_IF

Sending Workflow

Class StateReleaseCarrier
FUNCTION_BLOCK StateReleaseCarrier EXTENDS AbstractWorkflowState
VAR
	conveyorInterface :IConveyorInterface;
	stopperCylinder :ICylinder;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	conveyorInterface :IConveyorInterface;
	stopperCylinder :ICylinder;
END_VAR
THIS^.conveyorInterface := conveyorInterface;
THIS^.stopperCylinder := stopperCylinder;
METHOD executeState :IStatemachine
THIS^.conveyorInterface.setStartRequest();
THIS^.stopperCylinder.moveToWorkPosition();

IF (THIS^.conveyorInterface.conveyorIsRunning AND THIS^.stopperCylinder.isAtWorkPosition) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF
Class StateStartConveyor
FUNCTION_BLOCK StateStartConveyor EXTENDS AbstractWorkflowState
VAR
	conveyorInterface :IConveyorInterface;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	conveyorInterface :IConveyorInterface;
END_VAR
THIS^.conveyorInterface := conveyorInterface;
METHOD executeState :IStatemachine
THIS^.conveyorInterface.setStartRequest();
IF (THIS^.conveyorInterface.conveyorIsRunning) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF
Class StateStopNextCarrier
FUNCTION_BLOCK StateStopNextCarrier EXTENDS AbstractWorkflowState
VAR
	conveyorInterface :IConveyorInterface;
	stopperCylinder :ICylinder;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	conveyorInterface :IConveyorInterface;
	stopperCylinder :ICylinder;
END_VAR
THIS^.conveyorInterface := conveyorInterface;
THIS^.stopperCylinder := stopperCylinder;
METHOD executeState :IStatemachine
THIS^.conveyorInterface.setStartRequest();
THIS^.stopperCylinder.moveToHomePosition();

IF (THIS^.stopperCylinder.isAtHomePosition) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF

Class StateWaitForCarrierToSend
FUNCTION_BLOCK StateWaitForCarrierToSend EXTENDS AbstractWorkflowState
VAR
	stopperSensor 	:IDigitalSensor;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	stopperSensor :IDigitalSensor;
END_VAR
THIS^.stopperSensor := stopperSensor;
METHOD executeState :IStatemachine
IF (THIS^.stopperSensor.isOccupied) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF
Class StateWaitUntilCarrierIsArrived
FUNCTION_BLOCK StateWaitUntilCarrierIsArrived EXTENDS AbstractWorkflowState
VAR
	receiverInterface :ITransportInterfaceForSender;
	conveyorInterface :IConveyorInterface;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	receiverInterface :ITransportInterfaceForSender;
	conveyorInterface :IConveyorInterface;
END_VAR
THIS^.receiverInterface := receiverInterface;
THIS^.conveyorInterface := conveyorInterface;
METHOD executeState :IStatemachine
THIS^.conveyorInterface.setStartRequest();

IF ((
		THIS^.receiverInterface.partIsArrivedAtNext
	) OR (
		NOT THIS^.receiverInterface.nextIsReadyToRecive
	)
) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF
Class StateWaitUntilCarrierIsGone
FUNCTION_BLOCK StateWaitUntilCarrierIsGone EXTENDS AbstractWorkflowState
VAR
	stopperSensor :IDigitalSensor;
	conveyorInterface :IConveyorInterface;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	stopperSensor :IDigitalSensor;
	conveyorInterface :IConveyorInterface;
END_VAR
THIS^.stopperSensor := stopperSensor;
THIS^.conveyorInterface := conveyorInterface;
METHOD executeState :IStatemachine
THIS^.conveyorInterface.setStartRequest();

IF (THIS^.stopperSensor.isFree) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF
Class StateWaitUntilReceiverIsReady
FUNCTION_BLOCK StateWaitUntilReceiverIsReady EXTENDS AbstractWorkflowState
VAR
	receiverInterface :ITransportInterfaceForSender;
END_VAR
METHOD FB_init :BOOL
VAR_INPUT
	// if TRUE, the retain variables are initialized (warm start / cold start)
	bInitRetains :BOOL := FALSE;
	// if TRUE, the instance afterwards gets moved into the copy code (online change)
	bInCopyCode :BOOL := TRUE;
	
	nextState :IStatemachine;
	receiverInterface :ITransportInterfaceForSender;
END_VAR
THIS^.receiverInterface := receiverInterface;
METHOD executeState :IStatemachine
IF (THIS^.receiverInterface.nextIsReadyToRecive) THEN
	executeState := THIS^.nextState;
ELSE
	executeState := THIS^;
END_IF