/*
* Copyright (c) 2014, Jens Deters
* http://www.jensd.de
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.jensd.raspi.ui.ioboard;
import com.pi4j.io.gpio.PinMode;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import de.jensd.javafx.controls.indicator.Indicator;
import de.jensd.raspi.adapter.GpioAdapter;
import java.io.IOException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
/**
*
* @author Jens Deters
*/
public class IOBoard extends VBox {
private final static Logger LOGGER = Logger.getLogger(IOBoard.class.getName());
@FXML
private GridPane buttonGridPane;
@FXML
private ToggleButton toogleGPIO0;
@FXML
private ToggleButton toogleGPIO1;
@FXML
private ToggleButton toogleGPIO2;
@FXML
private ToggleButton toogleGPIO3;
@FXML
private ToggleButton toogleGPIO4;
@FXML
private ToggleButton toogleGPIO5;
@FXML
private ToggleButton toogleGPIO6;
@FXML
private ToggleButton toogleGPIO7;
@FXML
private ToggleButton toggleModeGPIO0;
@FXML
private ToggleButton toggleModeGPIO1;
@FXML
private ToggleButton toggleModeGPIO2;
@FXML
private ToggleButton toggleModeGPIO3;
@FXML
private ToggleButton toggleModeGPIO4;
@FXML
private ToggleButton toggleModeGPIO5;
@FXML
private ToggleButton toggleModeGPIO6;
@FXML
private ToggleButton toggleModeGPIO7;
@FXML
private Button exitButton;
@FXML
private VBox indicatorBox0;
@FXML
private VBox indicatorBox1;
@FXML
private VBox indicatorBox2;
@FXML
private VBox indicatorBox3;
@FXML
private VBox indicatorBox4;
@FXML
private VBox indicatorBox5;
@FXML
private VBox indicatorBox6;
@FXML
private VBox indicatorBox7;
@FXML
private ToggleButton gpioConnectToggleButton;
@FXML
private ResourceBundle resources;
private GpioAdapter gpioAdapter;
private Indicator indicatorGPIO0;
private Indicator indicatorGPIO1;
private Indicator indicatorGPIO2;
private Indicator indicatorGPIO3;
private Indicator indicatorGPIO4;
private Indicator indicatorGPIO5;
private Indicator indicatorGPIO6;
private Indicator indicatorGPIO7;
private ToggleButton[] toggleGPIOButtons;
private ToggleButton[] toggleGPIOModeButtons;
public IOBoard() {
init();
}
private void init() {
ResourceBundle resourceBundle = ResourceBundle.getBundle(getClass().getPackage().getName() + ".ioboard");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ioboard.fxml"));
fxmlLoader.setResources(resourceBundle);
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
AwesomeDude.setIcon(exitButton, AwesomeIcon.POWER_OFF, "2em");
gpioAdapter = new GpioAdapter();
indicatorGPIO0 = createIndicator();
indicatorGPIO1 = createIndicator();
indicatorGPIO2 = createIndicator();
indicatorGPIO3 = createIndicator();
indicatorGPIO4 = createIndicator();
indicatorGPIO5 = createIndicator();
indicatorGPIO6 = createIndicator();
indicatorGPIO7 = createIndicator();
indicatorBox0.getChildren().add(indicatorGPIO0);
indicatorBox1.getChildren().add(indicatorGPIO1);
indicatorBox2.getChildren().add(indicatorGPIO2);
indicatorBox3.getChildren().add(indicatorGPIO3);
indicatorBox4.getChildren().add(indicatorGPIO4);
indicatorBox5.getChildren().add(indicatorGPIO5);
indicatorBox6.getChildren().add(indicatorGPIO6);
indicatorBox7.getChildren().add(indicatorGPIO7);
indicatorGPIO0.passProperty().bindBidirectional(gpioAdapter.gpio0StateProperty());
indicatorGPIO1.passProperty().bindBidirectional(gpioAdapter.gpio1StateProperty());
indicatorGPIO2.passProperty().bindBidirectional(gpioAdapter.gpio2StateProperty());
indicatorGPIO3.passProperty().bindBidirectional(gpioAdapter.gpio3StateProperty());
indicatorGPIO4.passProperty().bindBidirectional(gpioAdapter.gpio4StateProperty());
indicatorGPIO5.passProperty().bindBidirectional(gpioAdapter.gpio5StateProperty());
indicatorGPIO6.passProperty().bindBidirectional(gpioAdapter.gpio6StateProperty());
indicatorGPIO7.passProperty().bindBidirectional(gpioAdapter.gpio7StateProperty());
gpioAdapter.gpio0ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO0));
gpioAdapter.gpio1ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO1));
gpioAdapter.gpio2ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO2));
gpioAdapter.gpio3ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO3));
gpioAdapter.gpio4ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO4));
gpioAdapter.gpio5ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO5));
gpioAdapter.gpio6ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO6));
gpioAdapter.gpio7ModeProperty().addListener(new IOModeChangeEventHandler(toggleModeGPIO7));
toggleModeGPIO0.setOnAction(new ToggleModeEventHandler(toggleModeGPIO0, 0));
toggleModeGPIO1.setOnAction(new ToggleModeEventHandler(toggleModeGPIO1, 1));
toggleModeGPIO2.setOnAction(new ToggleModeEventHandler(toggleModeGPIO2, 2));
toggleModeGPIO3.setOnAction(new ToggleModeEventHandler(toggleModeGPIO3, 3));
toggleModeGPIO4.setOnAction(new ToggleModeEventHandler(toggleModeGPIO4, 4));
toggleModeGPIO5.setOnAction(new ToggleModeEventHandler(toggleModeGPIO5, 5));
toggleModeGPIO6.setOnAction(new ToggleModeEventHandler(toggleModeGPIO6, 6));
toggleModeGPIO7.setOnAction(new ToggleModeEventHandler(toggleModeGPIO7, 7));
toogleGPIO0.visibleProperty().bind(toggleModeGPIO0.selectedProperty().not());
toogleGPIO1.visibleProperty().bind(toggleModeGPIO1.selectedProperty().not());
toogleGPIO2.visibleProperty().bind(toggleModeGPIO2.selectedProperty().not());
toogleGPIO3.visibleProperty().bind(toggleModeGPIO3.selectedProperty().not());
toogleGPIO4.visibleProperty().bind(toggleModeGPIO4.selectedProperty().not());
toogleGPIO5.visibleProperty().bind(toggleModeGPIO5.selectedProperty().not());
toogleGPIO6.visibleProperty().bind(toggleModeGPIO6.selectedProperty().not());
toogleGPIO7.visibleProperty().bind(toggleModeGPIO7.selectedProperty().not());
toogleGPIO0.selectedProperty().bindBidirectional(gpioAdapter.gpio0StateProperty());
toogleGPIO1.selectedProperty().bindBidirectional(gpioAdapter.gpio1StateProperty());
toogleGPIO2.selectedProperty().bindBidirectional(gpioAdapter.gpio2StateProperty());
toogleGPIO3.selectedProperty().bindBidirectional(gpioAdapter.gpio3StateProperty());
toogleGPIO4.selectedProperty().bindBidirectional(gpioAdapter.gpio4StateProperty());
toogleGPIO5.selectedProperty().bindBidirectional(gpioAdapter.gpio5StateProperty());
toogleGPIO6.selectedProperty().bindBidirectional(gpioAdapter.gpio6StateProperty());
toogleGPIO7.selectedProperty().bindBidirectional(gpioAdapter.gpio7StateProperty());
toggleGPIOButtons = new ToggleButton[]{
toogleGPIO0,
toogleGPIO1,
toogleGPIO2,
toogleGPIO3,
toogleGPIO4,
toogleGPIO5,
toogleGPIO6,
toogleGPIO7
};
toggleGPIOModeButtons = new ToggleButton[]{
toggleModeGPIO0,
toggleModeGPIO1,
toggleModeGPIO2,
toggleModeGPIO3,
toggleModeGPIO4,
toggleModeGPIO5,
toggleModeGPIO6,
toggleModeGPIO7
};
gpioConnectToggleButton.selectedProperty()
.addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean selected) -> {
if (!OS.isLinux()) {
LOGGER.info("Obviously not running on a Raspberry Pi. GPIO is not going to be connected.");
gpioConnectToggleButton.setSelected(false);
return;
}
if (selected) {
LOGGER.info("GPIO Connect");
gpioConnectToggleButton.setText(resources.getString("button.gpio.connected"));
onGpioConnect();
} else {
LOGGER.info("GPIO Disconnect");
gpioConnectToggleButton.setText(resources.getString("button.gpio.disconnected"));
onGpioDisconnect();
}
}
);
onReset();
}
private Indicator createIndicator() {
Indicator indicator = new Indicator();
indicator.setResult(Indicator.Result.FAIL);
indicator.setPrefSize(100.0, 100.0);
return indicator;
}
/*
* -------------------------- ACTIONS --------------------------
*/
@FXML
public void onTest() {
LOGGER.info("onTest");
for (ToggleButton toggleGPIOModeButton : toggleGPIOModeButtons) {
toggleGPIOModeButton.setSelected(false);
}
gpioAdapter.test(1000);
}
@FXML
public void onReset() {
LOGGER.info("onReset");
for (ToggleButton toggleGPIOModeButton : toggleGPIOModeButtons) {
toggleGPIOModeButton.setSelected(false);
}
gpioAdapter.reset();
}
public void onGpioDisconnect() {
LOGGER.info("onGpioDisconnect");
gpioAdapter.disconnect();
}
public void onGpioConnect() {
LOGGER.info("onGpioConnect");
gpioAdapter.connect();
}
@FXML
public void onExit() {
LOGGER.info("onExit");
Platform.exit();
System.exit(0);
}
private class ToggleModeEventHandler implements EventHandler<ActionEvent> {
private final ToggleButton button;
private final int pinNumber;
public ToggleModeEventHandler(final ToggleButton button, final int pinNumber) {
this.button = button;
this.pinNumber = pinNumber;
}
@Override
public void handle(ActionEvent t) {
toggleGPIOButtons[pinNumber].setSelected(false);
if (button.isSelected()) {
LOGGER.log(Level.INFO, "set Pin: {0} Mode: {1}", new Object[]{pinNumber, PinMode.DIGITAL_INPUT});
gpioAdapter.setGpioMode(pinNumber, PinMode.DIGITAL_INPUT);
} else {
LOGGER.log(Level.INFO, "set Pin: {0} Mode: {1}", new Object[]{pinNumber, PinMode.DIGITAL_OUTPUT});
gpioAdapter.setGpioMode(pinNumber, PinMode.DIGITAL_OUTPUT);
}
}
}
private class IOModeChangeEventHandler implements ChangeListener<PinMode> {
private final ToggleButton modeToggleButton;
public IOModeChangeEventHandler(final ToggleButton modeToggleButton) {
this.modeToggleButton = modeToggleButton;
modeToggleButton.setText("OUT");
}
@Override
public void changed(ObservableValue<? extends PinMode> ov, PinMode t, PinMode newMode) {
if (newMode.equals(PinMode.DIGITAL_OUTPUT)) {
modeToggleButton.setText("OUT");
} else {
modeToggleButton.setText("IN");
}
}
}
}