# SYSC 3303-L2 Group 9 Project

[![Build Status](https://travis-ci.com/anhuynh/sysc3303-project.svg?token=Wz5AU1a96qw7tYU4TpGQ&branch=master)](https://travis-ci.com/anhuynh/sysc3303-project)

### Group Members:
Keyan Cassis, Tuan Chau, Josh Gerwing, An Huynh, Justin Sigouin

## Set up instructions:
* Load project into Eclipse
* Run the FloorReceiver and ElevatorReceiver first and then run the SchedulerReceiver last

(if the ability to run on seperate computers is not required, passing no arguments will default IPs to localhost)

### Running on Seperate IPs
* Get IPs of the computer you will run the processes on (can be one IP if running all three processes locally)
* Set the main arguments as follows:
	* FloorReceiver takes in the IP of the computer that will run SchedulerReceiver
	* ElevatorReceiver takes in the IP of the computer that will run SchedulerReceiver
	* SchedulerReceiver takes in IP of the computer that will run the FloorReceiver as the first argument, and the IP of the computer that will run ElevatorReceiver as the second argument

## Reading the Output
* ElevatorReceiver's console will output the current state for the elevator whenever any of its states is changed, and should be viewed
* FloorReceiver's console will output the current state of any floor's lights that change
* SchedulerReceiver's console will output any received elevator requests and what elevator it has assigned to service the request

## Breakdown of Work Performed
Iteration 1
* Justin: Communication, floor, elevator, scheduler, unit tests
* Josh: Communication, input, floor, elevator, scheduler, UML, error, logging
* An: Communication, floor, elevator, scheduler, unit tests
* Keyan: Scheduler, elevator, config
* Tuan: Elevator, state machines

Iteration 2
* Justin: Elevator, unit tests, implement scheduler algorithim
* Josh: Elevator, UML sequence diagram, logging, readme updates
* An: Elevator, unit tests, implement scheduler algorithim
* Keyan: scheduler algorithim
* Tuan: UML class diagram, design scheduler algorithim, scheduler fixes

Iteration 3
* Justin: Handling timing error, fix all broken cases, finish door error
* Josh: Input file changes and creating error propagation, UML
* An: Handling timing error, fix all broken cases, finish door error
* Keyan: Start door error, elevator stuck timing diagram
* Tuan: Door stuck open and close timing diagram

Iteration 4
* Justin: Measurements, fix mean/variance, fix initializatin race condition, readme
* Josh: Record times for tasks, fix mean/variance, measurements
* An: Measurements, fix mean/variance, fix initializatin race condition, readme
* Keyan: Calculate mean/variance
* Tuan: Timing diagram update

### Logging
* Change the line in resources/logging.properties from .level= INFO to .level= ALL if you want to review all logs (including debug logs).

### Program Configuration
* Changing the values present in the data/config file will change how the system behaves (options for number of elevators, floors, times etc.).

### Editing Preconfigured Events
* Format: 1000,5,Up,8,3,6
* First part (1000)
	* When this input event occurs after the system starts, measured in ms.
* Second part (5)
	* Floor where the user presses the button to request an elevator
* Third part (Up)
	* Which button the user presses to request an elevator (only Up or Down)
* Fourth part (8)
	* Floor that the user requests after they've boarded the elevator
* Fifth part (3)
	* Type of error that will occur in this request.
	* 0 = no error
	* 1 = door stuck open
	* 2 = door stuck closed
	* 3 = elevator stuck trying to get to the floor specified in the next field
* Sixth part (6)
	* Which floor the error specified in part 5 occurs at

### Testing Different Scenarios
In `floor.input.InputParser`, change the `INPUT_FILE_LOCATION` to the specified file to test out a specfic scenario:
* All errors (default)
	* Use `floorEvents`
	* In the scheduler output:
		* elevator 1 will service request from 2 to 4 (with door getting stuck closed at floor 2)
		* elevator 2 will service request from 5 to 8 (with elevator getting stuck at floor 5)
		* elevator 3 will service request from 3 to 2 (with door getting stuck open at floor 3)
	* A severe log will be shown in the scheduler and elevator outputs whenever an error occurs
* Elevator stuck error
	* Use `elevatorStuckEvents`. The second input event, `1000,5,Up,8,3,5`, will cause the elevator to get stuck at floor 5
	* In the scheduler output, elevator 2 is assigned to service the error request
	* Now looking at the elevator output, follow the logs that say `elevatorId=2`. The logs show the floor and once the elevator passes floor 4, a SEVERE log will show there is an error there.
	* Look at the scheduler output, a log will show that the scheduler detected and error and takes elevator 2 out of service and reroutes any remaining requests to another available elevator


## Files:
See javadocs above each class for more detail on what each class does.
* List of files
	* common
		* AbstractReceiver.java
		* Direction.java
		* ErrorType.java
		* LogConsoleHandler.java
		* LoggerUtil.java
		* Motor.java
		* Util.java
	* communication
		* messages
			* ConfirmInitializeMessage.java
			* ElevatorActionMessage.java
			* ElevatorErrorOccuredMessage.java
			* ElevatorMoveMessage.java
			* ElevatorRequestMessage.java
			* ElevatorSensorMessage.java
			* FloorArrivalMessage.java
			* ForceActionConfirmedMessage.java
			* InitializeMessage.java
			* Message.java
			* StartEventsMessage.java
		* MessageSender.java
		* MessageUtil.java
		* Port.java
	* elevator
		* Elevator.java
		* ElevatorReceiver.java
		* ElevatorRequestFloorQueue.java
		* ElevatorSensor.java
		* ElevatorSubsystem.java
	* error
		* ExceptionUtil.java
		* InputFormatException.java
		* UnexpectedMessageTypeException.java
		* UnknownAddressException.java
	* floor
		* input
			* InputEvent.java
			* InputParser.java
		* Floor.java
		* FloorReceiver.java
		* FloorSubsystem.java
	* scheduler
		* ElevatorDispatchTask.java
		* ElevatorMovedTask.java
		* ElevatorTimerTask.java
		* MetaElevator.java
		* Scheduler.java
		* SchedulerReceiver.java
		* SchedulerTask.java
		* SchedulerTimer.java
		* SchedulerUtil.java
		* TaskTime.java
* Test files
	* communication
		* CommunicationTest.java
	* elevator
		* ElevatorSubsystemTest.java
	* floor
		* FloorSubsystemTest.java
		* FloorTest.java
	* scheduler
		* MetaElevatorTest.java
		* SchedulerUtilTest.java
* Data and resource files
	* data
		* config
		* floorEvents
		* elevatorStuckEvents
	* resources
		* logging.properties

### Notes of known issues
There are some timing issues

* If the system is overloaded and the scheduler decides that a certain elevator should add a request in the same direction as an elevator that has already passed the request floor, the elevator goes on infinitely
* If an elevator has stopped at a floor to service a request and an input event is being handled at the same time and is assigned to the stopped elevator, this causes the elevator to take both flows of actions and makes it look like the elevator is teleporting between the 2 requests

### Measurements for mean and variance (Iteration 4)
* Servicing an elevator request:
  * Mean: 3.130483333333333ms
  * Variance: 18.520061958055557ms
* Servicing an move request from inside the elevator:
  * Mean: 0.29561666666666664ms
  * Variance: 0.03293016972222223ms
* Processing an elevator moving between floors:
  * Mean: 0.6168432432432432ms
  * Variance: 0.033762382454346235ms
