Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed lib/spring-aop-5.3.19.jar
Binary file not shown.
Binary file removed lib/spring-beans-5.3.19.jar
Binary file not shown.
Binary file removed lib/spring-boot-1.5.15.RELEASE.jar
Binary file not shown.
Binary file removed lib/spring-boot-test-1.5.15.RELEASE.jar
Binary file not shown.
Binary file removed lib/spring-context-5.3.19.jar
Binary file not shown.
Binary file removed lib/spring-core-5.3.19.jar
Binary file not shown.
Binary file removed lib/spring-expression-5.3.19.jar
Binary file not shown.
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down
Binary file added src/main/Images/ChristmasLightsImage.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
111 changes: 88 additions & 23 deletions src/main/java/ScrumTeam1/LEDTree/LEDColorController.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,99 @@
package ScrumTeam1.LEDTree;

import com.pi4j.io.gpio.*;
import java.util.concurrent.TimeUnit;

//import com.pi4j.io.gpio.*; // imports the Pi4j that needs to be installed on the raspberry pi
//import java.util.concurrent.TimeUnit; // this is a time related operation for sleeping threads

public class LEDColorController { // Public or private?
/*
public static void main(String[] args) throws InterruptedException { // throws InterruptedException for color change
GpioController gpio = GpioFactory.getInstance();
GpioPinDigitalOutput redPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "Red", PinState.LOW);
GpioPinDigitalOutput bluePin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, "Blue", PinState.LOW);
GpioPinDigitalOutput greenPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "Green", PinState.LOW);

try {
// Change LED colors in a loop, we can change this to fit.
while (true) {
redPin.toggle();
TimeUnit.SECONDS.sleep(1); // all three of these are pausing for 1 second before changing
bluePin.toggle(); // Have to choose colors or repeat this for more color options
TimeUnit.SECONDS.sleep(1); // change second to fit whatever we want
greenPin.toggle();
TimeUnit.SECONDS.sleep(1);
/*
Ok so here is how this rewritten class works. toggleAndSleep governs
the on/off state of each pin. toggleAndSleep is used in the colorChange
method to switch between colors. runColorSequence then uses the colorChange method
in a loop to flip between colors making a sequence. There is a sequence shutdown method
that I've been meaning to write
*/


public class LEDColorController {
// Light sequence class

// variable where Gpio can store pin values

private GpioController gpio;
private GpioPinDigitalOutput redPin;
private GpioPinDigitalOutput bluePin;
private GpioPinDigitalOutput greenPin;



// Constructor that initializes each color pin with the variables. Because I had trouble understanding how
// Gpio works, and I was lazy I asked chatGPT to help me set this up
public LEDColorController() {
gpio = GpioFactory.getInstance();
redPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "Red", PinState.LOW);
bluePin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, "Blue", PinState.LOW);
greenPin = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "Green", PinState.LOW);
}

// This method uses a switch to switch each color. It is used in the loop to create
// a x-mas light type light sequence.
public void changeColor(LEDColor color) throws InterruptedException {
switch (color) {
case RED:
toggleAndSleep(redPin);
break;
case BLUE:
toggleAndSleep(bluePin);
break;
case GREEN:
toggleAndSleep(greenPin);
break;
}
}

// This is the actual sequence!!! This can be used with the switch above to create other light
// sequences. I'll add two more after we know this works.
public void runColorSequence(int sequenceCount, int colorDuration, int breakDuration) throws InterruptedException {
//int sequenceCount = 20; // The break condition for the loop
//int colorDuration = 2; // In seconds
//int breakDuration = 1; // In seconds - This is the time between colors.

for (int i = 0; i < sequenceCount; i++) {
changeColor(LEDColor.RED);
changeColor(LEDColor.BLUE);
changeColor(LEDColor.GREEN);

// Condition set to ensure that a break is not added after the last iteration of the loop
if (i < sequenceCount - 1) {
// If not the last iteration, add a break
TimeUnit.SECONDS.sleep(breakDuration);
// ^ This means that the loop will pause/sleep for the time amount
// specified in breakDuration
}
} finally {
gpio.shutdown();
}
}

*/
// This method toggles the pins for the changeColor method
private void toggleAndSleep(GpioPinDigitalOutput pin) throws InterruptedException {
pin.toggle();
TimeUnit.SECONDS.sleep(1);
}

// This is the shutdown method I've been meaning to write
public void shutdown() {
gpio.shutdown();
}

// This is an enumeration method. I had to add this in order to make the code a little more
//human-readable. This method also apparently makes the color "types" type safe.
// This was a suggested addition when I asked the ai to look over my code.
// I need to learn more about this so don't ask me to explain outside of the narrow use here.
public enum LEDColor {
RED,
BLUE,
GREEN
}
}





125 changes: 91 additions & 34 deletions src/main/java/ScrumTeam1/LEDTree/NumberSequenceUI.java
Original file line number Diff line number Diff line change
@@ -1,64 +1,121 @@
package ScrumTeam1.LEDTree;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.image.Image;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class NumberSequenceUI extends Application { // NumberSequenceUI uses Application abstract class
// !!!This class houses the JavaFX UI!!!

private Label output = new Label(); // Creates label object that is used to output the array index as text
// Not set since the output text is variable
SequenceArray sA = new SequenceArray(); // Creates object out of class SequenceArray where the Sequences
public class NumberSequenceUI extends Application {

// This Text object is used to output the array index as text
// It's not set initially with text since the output text is variable
private Text output = new Text();

// This object is created out of the SequenceArray class where the Sequences
// are stored in an array
private SequenceArray sA = new SequenceArray();



@Override
public void start(Stage primaryStage) { // Method and sets up the JavaFX window
primaryStage.setTitle("Select light sequence to play"); // Window title

// Button objects to call array indexes
Button sequence1Button = new Button("Sequence 1");
Button sequence2Button = new Button("Sequence 2");
Button sequence3Button = new Button("Sequence 3");
Button exitAppButton = new Button("Exit");

/* Objects that use method setOnAction that makes the button display the correct index from array "sequences"
using the getIndex method from instantiated object sA ("SequenceArray")
*/
// !!! Need some way to abort the sequence once executed !!!
// !!! Create number generator object to test cancel button !!!
public void start(Stage primaryStage) {
primaryStage.setTitle("The LED Tree!"); // Top windows bar text

//Button objects with their associated display text.
// Uses the method "createStyledButton" to consolidate format parameters and create the buttons - see below
// !!! Need to add cancel sequence button !!!
Button sequence1Button = createStyledButton("Sequence 1", "white");
Button sequence2Button = createStyledButton("Sequence 2", "white");
Button sequence3Button = createStyledButton("Sequence 3", "white");
Button actualSequenceButton = createStyledButton("Actual Light Sequence", "white");
Button cancelSequenceButton = createStyledButton("Cancel Sequence", "white");
Button exitAppButton = createStyledButton("Exit", "white");

// Sets what each button does - pull up "sequence" from array, or close program
sequence1Button.setOnAction(e -> displaySequence(0));
sequence2Button.setOnAction(e -> displaySequence(1));
sequence3Button.setOnAction(e -> displaySequence(2));
actualSequenceButton.setOnAction(e -> sA.getObjIndex(3)) ;
cancelSequenceButton.setOnAction((e -> sA.getObjIndexShutdown())); //!!!!!!
exitAppButton.setOnAction(e -> System.exit(0));

/* Vbox object. As I understand, Vbox is a container that will arrange the child (addAll) button vertically */
VBox vbox = new VBox(10); // 10 pixels specified between each button
vbox.getChildren().addAll(sequence1Button, sequence2Button, sequence3Button, exitAppButton, output);
// adds the display label below the button for output to screen (they are in order descending)
// Sets layout of the window
GridPane grid = new GridPane();
grid.setVgap(10);
grid.setHgap(10);
grid.setPadding(new Insets(20, 20, 20, 20)); // Padding for between display objects

// Add the text box at the top with the specified text
Text instructionText = new Text("Please choose a sequence to execute.");
instructionText.setStyle("-fx-font-size: 16; -fx-font-weight: 600; -fx-padding: 0 0 10 0;");

// Create a StackPane for the instruction text section
StackPane instructionPane = new StackPane(instructionText);
// Set styles for the instructionPane to have a white background, a black border, 2 pixels wide
// and some padding to separate text from the border
instructionPane.setStyle("-fx-background-color: white; -fx-border-color: black; -fx-border-width: 2; -fx-padding: 2;");
instructionPane.setAlignment(instructionText, javafx.geometry.Pos.CENTER); // Sets position of the text box

// Creates scene object that takes the vbox object and formats it to a size. Scene = the layout
// within the window
Scene scene = new Scene(vbox, 60, 200); // (40p W X 100p H)
primaryStage.setScene(scene); // Not super clear on this, but it seems to tie everything together in
// the code examples I studied
grid.add(instructionPane, 0, 0, 4, 1); // Spanning 4 columns

primaryStage.show(); // Shows everything
// Adds the sequence buttons to coordinates within the grid
grid.add(sequence1Button, 0, 1); // Column 0, row 1
grid.add(sequence2Button, 0, 2); // C0, r2
grid.add(sequence3Button, 0, 3); // C0, row3
grid.add(actualSequenceButton, 0,4);
grid.add(exitAppButton, 3, 1); // etc.

// Create a StackPane for the output section
StackPane outputPane = new StackPane(output);
// Set styles for the outputPane to have a white background, a black border, 2 pixels wide
// and some padding to separate text from the border
outputPane.setStyle("-fx-background-color: white; -fx-border-color: black; -fx-border-width: 2; -fx-padding: 5;");
outputPane.setAlignment(output, javafx.geometry.Pos.CENTER);

grid.add(outputPane, 0, 4, 4, 1); // Spanning 4 columns, placed in column 0 row 4

// Load the background image
Image backgroundImage = new Image("file:src/main/Images/ChristmasLightsImage.jpg"); // Background image directory - note: must use "file" keyword
BackgroundImage background = new BackgroundImage(backgroundImage, BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, new BackgroundSize(100, 100, true, true, true, true));
Background backgroundWithImage = new Background(background);
grid.setBackground(backgroundWithImage);

// Ties everything together as a scene object.
Scene scene = new Scene(grid, 600, 300);
primaryStage.setScene(scene);

primaryStage.show();
}

// Method used to display the correct sequence number. Calls the index directly from the button.
//The button uses the getIndex method to set and call the correct value
//Included a catch in case I modify this in the future and the index is out of bounds
// Method used to display the correct sequence number
// Calls the index directly from the button.
// The button uses the getIndex method to set and call the correct value
// Included a catch in case I modify this in the future and the index is out of bounds
private void displaySequence(int index) {
try {
String sequenceValue = sA.getObjIndex(index);
output.setText(sequenceValue);
output.setFill(Color.BLACK);
} catch (IllegalArgumentException e) {
output.setText("Invalid Selection: " + e.getMessage());
output.setFill(Color.RED);
}
}

// Method for centralizing the styling of the buttons, used above to create the buttons
private Button createStyledButton(String text, String backgroundColor) {
Button button = new Button(text); // Creates a button object.
// Calls setStyle method from button class with parameters
button.setStyle("-fx-font-size: 14; -fx-font-weight: BOLD; -fx-padding: 10 20; -fx-background-color: " + backgroundColor + ";");
return button;
}

}

32 changes: 21 additions & 11 deletions src/main/java/ScrumTeam1/LEDTree/SequenceArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ public class SequenceArray {
Sequence seq1 = new Sequence1();
Sequence seq2 = new Sequence2();
Sequence seq3 = new Sequence3();
LEDColorController actualLightSequence = new LEDColorController();


public SequenceArray() {
sequences = new int[]{1, 2, 3}; // Initializes the array with placeholders.
sequences = new int[]{1, 2, 3, 4}; // Initializes the array with placeholders.
// I'm not sure how to implement the actual sequences yet though.

objSeq = new Sequence[]{seq1, seq2, seq3};


objSeq = new Sequence[]{seq1, seq2, seq3, (Sequence) actualLightSequence};
}



// Loop that iterates over the test array to find an index value.
// "Index must be greater than or equal to 0 and no higher then the array length
public int getIndex (int index) {
Expand All @@ -34,12 +32,24 @@ public int getIndex (int index) {
}

// Loop that iterates over the actual sequence array to find an index value.
public String getObjIndex(int index) {
if (index >= 0 && index < objSeq.length) {
return objSeq[index].getStringValue();
}

throw new IllegalArgumentException("Invalid Selection: Index out of bounds");
// Depreciated old method

public void getObjIndexShutdown() {
actualLightSequence.shutdown();
}

// New method that uses conditionals to return two object types for the array
public String getObjIndex(int index) throws InterruptedException {
Object sequenceObj = getIndex(index);
if (sequenceObj instanceof Sequence) {
return ((Sequence) sequenceObj).getStringValue();
} else if (sequenceObj instanceof LEDColorController) {
((LEDColorController) sequenceObj).runColorSequence(20, 2, 1);
return "LED Sequence Cancelled";
} else {
throw new IllegalArgumentException("Invalid Selection: Index out of bounds");
}
}

}