Skip to content
Snippets Groups Projects
FXMLVueController.java 14.2 KiB
Newer Older
Salles Coralie's avatar
Salles Coralie committed
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Vue;

Puissegur Alexis's avatar
Puissegur Alexis committed
import Bluetooth.BluetoothManager;
import Bluetooth.BluetoothThread;
import Interfaces.Observable;
import Interfaces.Observer;
import MailUtil.MailUtil;
Puissegur Alexis's avatar
Puissegur Alexis committed
import Util.CalendarUtil;
Puissegur Alexis's avatar
Puissegur Alexis committed
import java.io.IOException;
Salles Coralie's avatar
Salles Coralie committed
import java.net.URL;
import java.time.LocalDate;
import java.time.Period;
Puissegur Alexis's avatar
Puissegur Alexis committed
import java.util.Calendar;
Salles Coralie's avatar
Salles Coralie committed
import java.util.ResourceBundle;
Puissegur Alexis's avatar
Puissegur Alexis committed
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
Salles Coralie's avatar
Salles Coralie committed
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.chart.CategoryAxis;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.chart.LineChart;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.control.Button;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.control.CheckBox;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.control.RadioButton;
import javafx.scene.control.Slider;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.GridPane;
Salles Coralie's avatar
Salles Coralie committed
import javafx.scene.layout.HBox;
Salles Coralie's avatar
Salles Coralie committed

Puissegur Alexis's avatar
Puissegur Alexis committed

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

Puissegur Alexis's avatar
Puissegur Alexis committed

Salles Coralie's avatar
Salles Coralie committed
/**
 * FXML Controller class
 *
 * @author invite
 */
Puissegur Alexis's avatar
Puissegur Alexis committed
public class FXMLVueController implements Initializable, Observer {
Salles Coralie's avatar
Salles Coralie committed
    //Page d'accueil
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private GridPane accueil;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Label temperature;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Label intensity;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Label humidityAir;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Label humidityPlante;
    @FXML
    private Label humiditySeuil;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private HBox planteHydrate;
    @FXML
    private HBox urgentArrosage;
Salles Coralie's avatar
Salles Coralie committed
    //Page de configuration
    @FXML
    private GridPane configuration;
    @FXML
    private Slider seuil;
    @FXML
    private Label seuilError;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private CheckBox arrosageAuto;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Button buttonBluetooth;
    @FXML
    private Label activationMessage;
Salles Coralie's avatar
Salles Coralie committed
    
Salles Coralie's avatar
Salles Coralie committed
    //Page de graphes
Salles Coralie's avatar
Salles Coralie committed
    @FXML
Salles Coralie's avatar
Salles Coralie committed
    private GridPane data;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
Salles Coralie's avatar
Salles Coralie committed
    private LineChart<Number, Number> graph;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
Salles Coralie's avatar
Salles Coralie committed
    private ToggleGroup granulation;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
Salles Coralie's avatar
Salles Coralie committed
    private ComboBox<String> dataGraph;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private NumberAxis axisYGraph;
    @FXML
    private CategoryAxis axisXGraph;
    @FXML
    private RadioButton dayGranulation;
    @FXML
    private RadioButton weekGranulation;
    @FXML
    private RadioButton monthGranulation;
Salles Coralie's avatar
Salles Coralie committed
    
    //Barre de menu avec les boutons
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Button buttonData;
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private Button buttonAccueil;
    @FXML
    private Button buttonConfig;
Salles Coralie's avatar
Salles Coralie committed
    private GridPane currentGridPane;
    private Button currentButton;
    private boolean alert;
    private boolean isConnected = false;
    private BluetoothManager bluetoothManager;
Puissegur Alexis's avatar
Puissegur Alexis committed
    private BluetoothThread workingThread;
    LocalDate lastMailDay;
Salles Coralie's avatar
Salles Coralie committed

Salles Coralie's avatar
Salles Coralie committed
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
Puissegur Alexis's avatar
Puissegur Alexis committed
        bluetoothManager = new BluetoothManager(this);
Salles Coralie's avatar
Salles Coralie committed
        alert = false;
        //Put the gridPane Accueil visible
        currentGridPane = accueil;
Salles Coralie's avatar
Salles Coralie committed
        currentButton = buttonAccueil;
Salles Coralie's avatar
Salles Coralie committed
        openPage(accueil, buttonAccueil);
        
        //TODO initialize lastMailDay with database
        lastMailDay = LocalDate.of(2018, 12, 12);

        seuil.valueProperty().addListener(new ChangeListener<Number>() {
Puissegur Alexis's avatar
Puissegur Alexis committed
            public void changed(ObservableValue<? extends Number> obs, Number oldVal, Number newVal) {
                int intVal = ((int) Math.round(newVal.doubleValue())/10)*10;
Puissegur Alexis's avatar
Puissegur Alexis committed
                int intOld = ((int) Math.round(oldVal.doubleValue())/10)*10;
                seuil.setValue(intVal);
                humiditySeuil.setText(""+intVal);
Puissegur Alexis's avatar
Puissegur Alexis committed
                
Puissegur Alexis's avatar
Puissegur Alexis committed
                if(humidityPlante.getText() != null && intVal <= Integer.parseInt(humidityPlante.getText()) && intOld > Integer.parseInt(humidityPlante.getText())){ // STOP
Puissegur Alexis's avatar
Puissegur Alexis committed
                    boolean tmp = true;
Puissegur Alexis's avatar
Puissegur Alexis committed
                    changeImagePlante(false);
Puissegur Alexis's avatar
Puissegur Alexis committed
                    while(tmp){
                        try{
                            System.out.println("STOP");
                            workingThread.sendInstruction("STOP");
                            tmp = false;              
                        } catch(IOException e){
                            e.printStackTrace();
Puissegur Alexis's avatar
Puissegur Alexis committed
                    }
Puissegur Alexis's avatar
Puissegur Alexis committed
                } else if(intVal > Integer.parseInt(humidityPlante.getText())){
Puissegur Alexis's avatar
Puissegur Alexis committed
                    changeImagePlante(true);
                    
Puissegur Alexis's avatar
Puissegur Alexis committed
                }
Puissegur Alexis's avatar
Puissegur Alexis committed
        //Bind the label for the senewValueuil in Accueil and the value in configurations
        //humiditySeuil.textProperty().bind(Bindings.convert(seuil.valueProperty()));
Salles Coralie's avatar
Salles Coralie committed
        
        humidityPlante.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
Puissegur Alexis's avatar
Puissegur Alexis committed
                System.out.println(oldValue);
                System.out.println(newValue);
                if (humiditySeuil.getText() != null && Integer.parseInt(newValue) < Integer.parseInt(humiditySeuil.getText())) {
Salles Coralie's avatar
Salles Coralie committed
                    changeImagePlante(true);
                    alert = true;
                    if(Integer.parseInt(oldValue) >  Integer.parseInt(humiditySeuil.getText()) || Integer.parseInt(oldValue) == -1){ // start or change
Puissegur Alexis's avatar
Puissegur Alexis committed
                        work();
                    }
Puissegur Alexis's avatar
Puissegur Alexis committed
                    if(alert){
                        changeImagePlante(false);
                    }          
                    boolean tmp = true;
                    while(tmp){
                        try{
                            System.out.println("STOP");
                            workingThread.sendInstruction("STOP");
                            tmp = false;              
                        } catch(IOException e){
                            e.printStackTrace();
Puissegur Alexis's avatar
Puissegur Alexis committed
                    }
Salles Coralie's avatar
Salles Coralie committed
                }
Salles Coralie's avatar
Salles Coralie committed
            }        
Salles Coralie's avatar
Salles Coralie committed
        });
Salles Coralie's avatar
Salles Coralie committed
        
        //Graph
        axisYGraph.setLabel("données");
        axisXGraph.setLabel("temps");
        XYChart.Series serieLine = new XYChart.Series();
        serieLine.getData().add(new XYChart.Data<>(14+"", 12));
        graph.getData().add(serieLine);
        graph.setLegendVisible(false);
        
        initDB("plant.db");
Salles Coralie's avatar
Salles Coralie committed
    }    

    public static void initDB(String name) {
 
        String url = "jdbc:sqlite:C:/sqlite/" + name;
 
        try (Connection conn = DriverManager.getConnection(url)) {
            if (conn != null) {
                DatabaseMetaData meta = conn.getMetaData();
                createNewTable(url);
            }
 
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
    
    
    /**
     * Create a new table in the test database
     *
     */
    public static void createNewTable(String url) {
        // SQLite connection string
        
        // SQL statement for creating a new table
        String sql = "CREATE TABLE IF NOT EXISTS data (\n"
                + "	id integer PRIMARY KEY AUTOINCREMENT,\n"
                + "     month integer NOT NULL CHECK(month <= 12 and month > 0),\n"
                + "     day integer NOT NULL CHECK(day <= 31 and day > 0),\n"
                + "     hour integer NOT NULL CHECK(hour <24 and hour >= 0),\n"
                + "     min integer NOT NULL CHECK(min <60 and min >= 0),\n"
                + "	intensity integer,\n"
                + "     temperature integer,\n"
                + "	humidityAir integer,\n"
                + "     humidityPlant integer\n"
                + ");";
        
        try (Connection conn = DriverManager.getConnection(url);
                Statement stmt = conn.createStatement()) {
            // create a new table
            stmt.execute(sql);
        } catch (SQLException e) {
            System.out.println("ewi" + e.getMessage());
        }
    }
    
     private Connection connect() {
        // SQLite connection string
        String url = "jdbc:sqlite:C://sqlite/plant.db";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }
     
    public void insert(int month, int day, int hour, int min, int it, int temp, int humiA, int humiT) {
        String sql = "INSERT INTO data(month,day,hour,min,intensity,temperature,humidityAir,humidityPlant) VALUES(?,?,?,?,?,?,?,?)";
 
        try (Connection conn = this.connect();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, month);
            pstmt.setInt(2, day);
            pstmt.setInt(3, hour);
            pstmt.setInt(4, min);
            pstmt.setInt(5, it);
            pstmt.setInt(6, temp);
            pstmt.setInt(7, humiA);
            pstmt.setInt(8, humiT);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
    
Salles Coralie's avatar
Salles Coralie committed
    /**
     * Change the text for activate or desactivate according to the checkbox
     * @param event 
     */
    @FXML
    private void clickAuto(ActionEvent event) {
        if(arrosageAuto.isSelected()){
            arrosageAuto.setText("Activé");
        }
        else arrosageAuto.setText("Désactivé");
Salles Coralie's avatar
Salles Coralie committed
    }
Salles Coralie's avatar
Salles Coralie committed

Salles Coralie's avatar
Salles Coralie committed
    /**
     * Button to activate the bluetooth
     * @param event 
     */
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private void clickActivationBluetooth(ActionEvent event) {
        if(!this.isConnected){
           isConnected = bluetoothManager.launch();
        }
        
        if(isConnected){
            try {
                bluetoothManager.startThread();
Puissegur Alexis's avatar
Puissegur Alexis committed
                this.workingThread = bluetoothManager.getWorkingThread();
                this.activationMessage.setText("Connection bluetooth activée");
Salles Coralie's avatar
Salles Coralie committed
                this.activationMessage.setStyle("-fx-background-color: #7fca5eff");
                this.buttonBluetooth.setDisable(true);
            } catch (Exception ex) {
Puissegur Alexis's avatar
Puissegur Alexis committed
                ex.printStackTrace();
Salles Coralie's avatar
Salles Coralie committed
    }
Salles Coralie's avatar
Salles Coralie committed
    
Salles Coralie's avatar
Salles Coralie committed
    /**
     * 
     * @param obs 
     */
Puissegur Alexis's avatar
Puissegur Alexis committed
    @Override
    public void update(Observable obs) {
Puissegur Alexis's avatar
Puissegur Alexis committed
        if(obs instanceof BluetoothThread && ((BluetoothThread) obs).equals(this.workingThread)){
Puissegur Alexis's avatar
Puissegur Alexis committed
            BluetoothThread t = (BluetoothThread) obs;
Puissegur Alexis's avatar
Puissegur Alexis committed
            String[] values = t.getBuffer().split(";");    
            
Puissegur Alexis's avatar
Puissegur Alexis committed
            Platform.runLater(
                () -> {                    
Puissegur Alexis's avatar
Puissegur Alexis committed
                    this.humidityAir.setText(values[0].replaceFirst("^0+(?!$)", ""));
                    this.intensity.setText(values[1].replaceFirst("^0+(?!$)", ""));
                    this.temperature.setText(values[2].replaceFirst("^0+(?!$)", ""));
                    this.humidityPlante.setText(values[3].replaceFirst("^0+(?!$)", ""));
Puissegur Alexis's avatar
Puissegur Alexis committed
        }
Salles Coralie's avatar
Salles Coralie committed
    /**
Puissegur Alexis's avatar
Puissegur Alexis committed
     * Update the view with the right image of the plant
Salles Coralie's avatar
Salles Coralie committed
     * @param alertM 
     */
    public void changeImagePlante(boolean alertM){
        if(alertM){
            this.planteHydrate.setVisible(false);
            this.urgentArrosage.setVisible(true);
        }
        else{
            this.urgentArrosage.setVisible(false);
            this.planteHydrate.setVisible(true);
        }
    }
Salles Coralie's avatar
Salles Coralie committed
    /**
Salles Coralie's avatar
Salles Coralie committed
     * Change the page for the grah page when clicking on data button
     * @param event 
     */
Salles Coralie's avatar
Salles Coralie committed
    @FXML
    private void clickData(ActionEvent event) {
Salles Coralie's avatar
Salles Coralie committed
        openPage(data, buttonData);
    }
    
    /**
     * Change the page for the accueil page when clicking on accueil button
     * @param event 
     */
    @FXML
    private void clickAccueil(ActionEvent event) {
        openPage(accueil, buttonAccueil);
    }

    /**
     * Change the page for the configuration page when clicking on configuration button
     * @param event 
     */
    @FXML
    private void clickConfig(ActionEvent event) {
       openPage(configuration, buttonConfig);
    }
    
    private void openPage(GridPane open, Button justClicked){
Salles Coralie's avatar
Salles Coralie committed
        currentGridPane.setVisible(false);
Salles Coralie's avatar
Salles Coralie committed
        open.setVisible(true);
        currentGridPane = open;
Salles Coralie's avatar
Salles Coralie committed
        currentButton.setStyle("-fx-background-color: #d5d5d5ff");
Salles Coralie's avatar
Salles Coralie committed
        currentButton = justClicked;
Salles Coralie's avatar
Salles Coralie committed
        currentButton.setStyle("-fx-background-color: #7fca5eff");
    }
Salles Coralie's avatar
Salles Coralie committed
    
Puissegur Alexis's avatar
Puissegur Alexis committed
    private void work(){
        computeGravity();
Puissegur Alexis's avatar
Puissegur Alexis committed
        if(CalendarUtil.isBusinessDay(Calendar.getInstance())){
            System.out.println("is business day");
Puissegur Alexis's avatar
Puissegur Alexis committed
        } else {
            System.out.println("is not business day");
            LocalDate today = LocalDate.now();
            Period difference = Period.between(lastMailDay, today);
            if(difference.getDays() > 1){
                // send mail
                MailUtil.sendDistressMail();
                lastMailDay = today;
            }
Puissegur Alexis's avatar
Puissegur Alexis committed
        }
    }
    
    public void computeGravity(){
      int humidity = Integer.parseInt(humidityPlante.getText().replaceFirst("^0+(?!$)", ""));
      int seuil = Integer.parseInt(humiditySeuil.getText().replaceFirst("^0+(?!$)", ""));
      System.out.println("humi " + humidity);
      System.out.println("seuil : " + seuil);
      if(humidity < (seuil / 2)) { // la moitié du seuil = critique, sound
Puissegur Alexis's avatar
Puissegur Alexis committed
          boolean tmp = true;
          while(tmp){
              try{
              this.workingThread.sendInstruction("SOUND");
              System.out.println("SOUND");
Puissegur Alexis's avatar
Puissegur Alexis committed
              tmp = false;              
              } catch(IOException e){
                  e.printStackTrace();
              }    
          }
          
      } else { // light
          boolean tmp = true;
          while(tmp){
              try{
              this.workingThread.sendInstruction("LIGHT");
              System.out.println("LIGHT");
Puissegur Alexis's avatar
Puissegur Alexis committed
              tmp = false;              
              } catch(IOException e){
                  e.printStackTrace();
              }    
          }
      }
Puissegur Alexis's avatar
Puissegur Alexis committed
    }
Salles Coralie's avatar
Salles Coralie committed
}