Skip to content
Snippets Groups Projects
FXMLVueController.java 17.4 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 DAO.SQLiteManager;
Puissegur Alexis's avatar
Puissegur Alexis committed
import Interfaces.Observable;
import Interfaces.Observer;
import MailUtil.MailUtil;
import Model.ComboboxModel;
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.*;
Salles Coralie's avatar
Salles Coralie committed
import javafx.geometry.Side;
import javafx.scene.control.TextField;
Salles Coralie's avatar
Salles Coralie committed

import javafx.scene.control.Toggle;
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 {
    
    public static final int MONTH = 333;
    public static final int WEEK = 666;
    public static final int DAY = 999;
    
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;
Salles Coralie's avatar
Salles Coralie committed
    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
    @FXML
    private TextField emailAddress;
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
    private LineChart<String, 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;
    private LocalDate lastMailDay;
    private SQLiteManager DBManager;
    private HashMap<String, ComboboxModel> currentMap;
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
        
        dataGraph.valueProperty().addListener(new ChangeListener<String>() {
            @Override public void changed(ObservableValue ov, String t, String t1) {
                ComboboxModel selected = currentMap.get(t1);
                    if(selected != null){
                        if(selected.getDay() == -1 && selected.getWeek() == -1){ // month
                        drawGraph(selected,MONTH);
                        
                    } else if(selected.getWeek() == -1){ // day
                        DBManager.selectDayOfMonthData(selected.getMonth(), selected.getDay());
                    } else  { // week 
                        DBManager.selectWeekOfMonthData(selected.getMonth(), selected.getWeek());
                    }
                }
            }    
        });
        
        granulation.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
            public void changed(ObservableValue<? extends Toggle> ov,
                Toggle old_toggle, Toggle new_toggle) {
                RadioButton rb = (RadioButton) new_toggle.getToggleGroup().getSelectedToggle();
                if (dayGranulation.equals(rb)) {
                    dataGraph.getItems().clear();
                    currentMap = DBManager.selectDayOfMonths();
                    dataGraph.getItems().addAll(currentMap.keySet());
                    
                } else if(weekGranulation.equals(rb)){
                    dataGraph.getItems().clear();
                    currentMap = DBManager.selectWeekOfMonth();
                    dataGraph.getItems().addAll(currentMap.keySet());
                    
                } else if(monthGranulation.equals(rb)) {
                    dataGraph.getItems().clear();
                    currentMap = DBManager.selectMonth();
                    dataGraph.getItems().addAll(currentMap.keySet());
Salles Coralie's avatar
Salles Coralie committed
        //Graph
        axisXGraph.setLabel("Temps");  
        axisXGraph.setAnimated(false);
        DBManager = new SQLiteManager("plant.db");
Masson Lea's avatar
Masson Lea committed
        if(!DBManager.selectYear(LocalDate.now().getYear()).isEmpty()){
Puissegur Alexis's avatar
Puissegur Alexis committed
            DBManager.purge(LocalDate.now().getYear());
Masson Lea's avatar
Masson Lea committed
        }
Salles Coralie's avatar
Salles Coralie committed
    }    

    public void drawGraph(ComboboxModel selected, int mode){
        ArrayList<ArrayList<DataModel>> res = null;
        graph.getData().clear();
            switch(mode){
                case MONTH:
                    res = DBManager.selectMonthData(selected.getMonth());
                    graph.setTitle("Visualisation mois : " + SQLiteManager.months[selected.getMonth()]);
                    break;
                case WEEK: 
                    res = DBManager.selectWeekOfMonthData(selected.getMonth(),selected.getWeek());
                    graph.setTitle("Visualisation " + SQLiteManager.months[selected.getMonth()] + " sem. " + selected.getWeek());
                    break;
                case DAY:
                    res = DBManager.selectDayOfMonthData(selected.getMonth(),selected.getDay());
                    graph.setTitle("Visualisation " + selected.getDay() + " " + SQLiteManager.months[selected.getMonth()]);
                    break;
                default:
                    graph.setTitle("???");
                    break;
            }
                                     
            LineChart.Series series1 = new LineChart.Series();
            LineChart.Series series2 = new LineChart.Series();
            LineChart.Series series3 = new LineChart.Series();
            LineChart.Series series4 = new LineChart.Series();

Salles Coralie's avatar
Salles Coralie committed
            series1.setName("Luminosité");
            series2.setName("Température");
            series3.setName("Humidité air");                   
            series4.setName("Humidité plante");
           
Salles Coralie's avatar
Salles Coralie committed
                series1.getData().add(new XYChart.Data<>(dm.getKey()+"",dm.getValue()));
            }
            for(DataModel dm : res.get(1)){
                series2.getData().add(new XYChart.Data(dm.getKey(),dm.getValue()));
            }
            for(DataModel dm : res.get(2)){
                series3.getData().add(new XYChart.Data(dm.getKey(),dm.getValue()));
            }
            for(DataModel dm : res.get(3)){
                series4.getData().add(new XYChart.Data(dm.getKey(),dm.getValue()));
Salles Coralie's avatar
Salles Coralie committed
            }    
Masson Lea's avatar
Masson Lea committed
                           
            graph.getData().addAll(series1,series2,series3,series4);
Masson Lea's avatar
Masson Lea committed
            
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(
                () -> {                    
                    this.humidityAir.setText(values[0].trim().replaceFirst("^0+(?!$)", ""));
                    this.intensity.setText(values[1].trim().replaceFirst("^0+(?!$)", ""));
                    this.temperature.setText(values[2].trim().replaceFirst("^0+(?!$)", ""));
                    this.humidityPlante.setText(values[3].trim().replaceFirst("^0+(?!$)", ""));
                }
            );     
           
            if(areValidNumbers(values)){
Masson Lea's avatar
Masson Lea committed
                DBManager.insert(Calendar.getInstance().get(Calendar.YEAR),
                    Calendar.getInstance().get(Calendar.MONTH),
                    Calendar.getInstance().get(Calendar.WEEK_OF_MONTH),
                    Calendar.getInstance().get(Calendar.DAY_OF_MONTH),
                    Calendar.getInstance().get(Calendar.HOUR_OF_DAY),
                    Calendar.getInstance().get(Calendar.MINUTE),
                    Integer.parseInt(values[1].trim().replaceFirst("^0+(?!$)", "")),
                    Integer.parseInt(values[2].trim().replaceFirst("^0+(?!$)", "")),
                    Integer.parseInt(values[0].trim().replaceFirst("^0+(?!$)", "")),
                    Integer.parseInt(values[3].trim().replaceFirst("^0+(?!$)", "")));
            } else {
                System.out.println("UNVALID");
            }
            
        }
    }
    
    static boolean areValidNumbers(String[] values) {
        // Return true if all characters are digits.
        for(String value : values){
            for (int i = 0; i < value.length(); i++) {
                if (!Character.isDigit(value.charAt(i))) {
                    return false;
Puissegur Alexis's avatar
Puissegur Alexis committed
                }
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);
Salles Coralie's avatar
Salles Coralie committed
       
Salles Coralie's avatar
Salles Coralie committed
    }
    
    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(){
        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
tcoulin's avatar
tcoulin committed
                MailUtil.sendDistressMail(this.humidityPlante.getText(), this.humiditySeuil.getText());
                lastMailDay = today;
            }
Puissegur Alexis's avatar
Puissegur Alexis committed
        }
    }
    
    public void computeGravity(){
      int humidity = Integer.parseInt(humidityPlante.getText().trim().replaceFirst("^0+(?!$)", ""));
      int seuil = Integer.parseInt(humiditySeuil.getText().trim().replaceFirst("^0+(?!$)", ""));
      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
}