/* * 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; import Bluetooth.BluetoothManager; import Bluetooth.BluetoothThread; import Interfaces.Observable; import Interfaces.Observer; import MailUtil.MailUtil; import Util.CalendarUtil; import java.io.IOException; import java.net.URL; import java.time.LocalDate; import java.time.Period; import java.util.Calendar; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.Slider; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; 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.*; /** * FXML Controller class * * @author invite */ public class FXMLVueController implements Initializable, Observer { //Page d'accueil @FXML private GridPane accueil; @FXML private Label temperature; @FXML private Label intensity; @FXML private Label humidityAir; @FXML private Label humidityPlante; @FXML private Label humiditySeuil; @FXML private HBox planteHydrate; @FXML private HBox urgentArrosage; //Page de configuration @FXML private GridPane configuration; @FXML private Slider seuil; @FXML private Label seuilError; @FXML private CheckBox arrosageAuto; @FXML private Button buttonBluetooth; @FXML private Label activationMessage; //Page de graphes @FXML private GridPane data; @FXML private LineChart<Number, Number> graph; @FXML private ToggleGroup granulation; @FXML private ComboBox<String> dataGraph; @FXML private NumberAxis axisYGraph; @FXML private CategoryAxis axisXGraph; @FXML private RadioButton dayGranulation; @FXML private RadioButton weekGranulation; @FXML private RadioButton monthGranulation; //Barre de menu avec les boutons @FXML private Button buttonData; @FXML private Button buttonAccueil; @FXML private Button buttonConfig; private GridPane currentGridPane; private Button currentButton; private boolean alert; private boolean isConnected = false; private BluetoothManager bluetoothManager; private BluetoothThread workingThread; LocalDate lastMailDay; /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { bluetoothManager = new BluetoothManager(this); alert = false; //Put the gridPane Accueil visible currentGridPane = accueil; currentButton = buttonAccueil; openPage(accueil, buttonAccueil); //TODO initialize lastMailDay with database lastMailDay = LocalDate.of(2018, 12, 12); seuil.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> obs, Number oldVal, Number newVal) { int intVal = ((int) Math.round(newVal.doubleValue())/10)*10; int intOld = ((int) Math.round(oldVal.doubleValue())/10)*10; seuil.setValue(intVal); humiditySeuil.setText(""+intVal); if(humidityPlante.getText() != null && intVal <= Integer.parseInt(humidityPlante.getText()) && intOld > Integer.parseInt(humidityPlante.getText())){ // STOP boolean tmp = true; changeImagePlante(false); while(tmp){ try{ System.out.println("STOP"); workingThread.sendInstruction("STOP"); tmp = false; } catch(IOException e){ e.printStackTrace(); } } } else if(intVal > Integer.parseInt(humidityPlante.getText())){ work(); changeImagePlante(true); } } }); //Bind the label for the senewValueuil in Accueil and the value in configurations //humiditySeuil.textProperty().bind(Bindings.convert(seuil.valueProperty())); humidityPlante.textProperty().addListener(new ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { System.out.println(oldValue); System.out.println(newValue); if (humiditySeuil.getText() != null && Integer.parseInt(newValue) < Integer.parseInt(humiditySeuil.getText())) { changeImagePlante(true); alert = true; if(Integer.parseInt(oldValue) > Integer.parseInt(humiditySeuil.getText()) || Integer.parseInt(oldValue) == -1){ // start or change work(); } } else { if(alert){ changeImagePlante(false); } boolean tmp = true; while(tmp){ try{ System.out.println("STOP"); workingThread.sendInstruction("STOP"); tmp = false; } catch(IOException e){ e.printStackTrace(); } } } } }); //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"); } 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()); } } /** * 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é"); } /** * Button to activate the bluetooth * @param event */ @FXML private void clickActivationBluetooth(ActionEvent event) { if(!this.isConnected){ isConnected = bluetoothManager.launch(); } if(isConnected){ try { bluetoothManager.startThread(); this.workingThread = bluetoothManager.getWorkingThread(); this.activationMessage.setText("Connection bluetooth activée"); this.activationMessage.setStyle("-fx-background-color: #7fca5eff"); this.buttonBluetooth.setDisable(true); } catch (Exception ex) { ex.printStackTrace(); } } } /** * * @param obs */ @Override public void update(Observable obs) { if(obs instanceof BluetoothThread && ((BluetoothThread) obs).equals(this.workingThread)){ BluetoothThread t = (BluetoothThread) obs; String[] values = t.getBuffer().split(";"); Platform.runLater( () -> { 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+(?!$)", "")); } ); } } /** * Update the view with the right image of the plant * @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); } } /** * Change the page for the grah page when clicking on data button * @param event */ @FXML private void clickData(ActionEvent event) { 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){ currentGridPane.setVisible(false); open.setVisible(true); currentGridPane = open; currentButton.setStyle("-fx-background-color: #d5d5d5ff"); currentButton = justClicked; currentButton.setStyle("-fx-background-color: #7fca5eff"); } private void work(){ computeGravity(); if(CalendarUtil.isBusinessDay(Calendar.getInstance())){ System.out.println("is business day"); } 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; } } } 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 boolean tmp = true; while(tmp){ try{ this.workingThread.sendInstruction("SOUND"); System.out.println("SOUND"); tmp = false; } catch(IOException e){ e.printStackTrace(); } } } else { // light boolean tmp = true; while(tmp){ try{ this.workingThread.sendInstruction("LIGHT"); System.out.println("LIGHT"); tmp = false; } catch(IOException e){ e.printStackTrace(); } } } } }