serialinterface/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.java

291 lines
11 KiB
Java

package de.gurkengewuerz.serialinterface;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import org.pmw.tinylog.Logger;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by gurkengewuerz.de on 08.01.2018.
*/
public class SerialGUI {
private JTabbedPane tabbedPane1;
private JButton refreshButton;
private JTextField a0000TextField;
private JTextArea debugArea;
private JButton sendButton;
private JTextField txText;
private JTextField a8652TextField;
private JButton connectButton;
private JButton startServerButton;
public JPanel mainPanel;
private JList comPorts;
private JSlider kmhSlider;
private JSpinner fuelSpinner;
private JSlider rpmSlider;
private JCheckBox rTurnSignalCheckBox;
private JCheckBox lTurnSignalCheckBox;
private JCheckBox handbrakeCheckBox;
private JCheckBox fogBeamCheckBox;
private JCheckBox highBeamCheckBox;
private JCheckBox seatBeltCheckBox;
private JCheckBox lowVoltageCheckBox;
private JCheckBox waterTempCheckBox;
private JCheckBox ABSCheckBox;
private JCheckBox tirePressureCheckBox;
private JCheckBox backlightCheckBox;
private JButton updateButton;
private JCheckBox offroadCheckBox;
private JCheckBox oilPressureCheckBox;
private JCheckBox openDoorsCheckBox;
private JCheckBox kupplungCheckBox;
private JCheckBox checkLampCheckBox;
private JCheckBox openTrunkCheckBox;
private JLabel rpmCounter;
private JLabel kmhCounter;
private JPanel simulatorPanel;
private SerialPort serialPort;
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 2000;
private static final int BAUDRATE = 115200; // ~ 14 kByte pro Sekunde
private DashboardStatus status;
private ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
/*
TODO: Klasse für Ansteuerung
TODO: WebServer
TODO: Update Simulation Panel if Class for contol gets updated! (Live View)
*/
public SerialGUI() {
status = new DashboardStatus();
Logger.info(String.join(",", listPorts()));
refreshPortList();
SpinnerModel sm = new SpinnerNumberModel(100, 0, 100, 5);
fuelSpinner.setModel(sm);
Hashtable labelsKMH = new Hashtable();
labelsKMH.put(0, new JLabel("0 km/h"));
labelsKMH.put(40, new JLabel("40 km/h"));
labelsKMH.put(80, new JLabel("80 km/h"));
labelsKMH.put(120, new JLabel("120 km/h"));
labelsKMH.put(160, new JLabel("160 km/h"));
labelsKMH.put(200, new JLabel("200 km/h"));
labelsKMH.put(240, new JLabel("240 km/h"));
kmhSlider.setLabelTable(labelsKMH);
kmhSlider.addChangeListener(evt -> {
JSlider slider = (JSlider) evt.getSource();
if (!slider.getValueIsAdjusting()) {
int value = slider.getValue();
kmhCounter.setText(value + " km/h");
}
});
Hashtable labelsRPM = new Hashtable();
labelsRPM.put(0, new JLabel("0"));
labelsRPM.put(1000, new JLabel("1k"));
labelsRPM.put(2000, new JLabel("2k"));
labelsRPM.put(3000, new JLabel("3k"));
labelsRPM.put(4000, new JLabel("4k"));
labelsRPM.put(5000, new JLabel("5k"));
labelsRPM.put(6000, new JLabel("6k"));
labelsRPM.put(7000, new JLabel("7k"));
labelsRPM.put(8000, new JLabel("8k"));
rpmSlider.setLabelTable(labelsRPM);
rpmSlider.addChangeListener(evt -> {
JSlider slider = (JSlider) evt.getSource();
if (!slider.getValueIsAdjusting()) {
int value = slider.getValue();
rpmCounter.setText("RPM: " + value);
}
});
refreshButton.addActionListener(e -> {
refreshPortList();
comPorts.grabFocus();
});
connectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (serialPort == null) {
try {
if (comPorts.getSelectedIndex() < 0) {
errorBox("Please select a COM Port!", "No port selected");
return;
}
CommPortIdentifier portId = getPortIDbyString((String) comPorts.getSelectedValue());
if (portId == null) {
errorBox("An invalid port is selected!\nIs the port still connected?", "Invalid port selected");
refreshPortList();
return;
}
// open serial port, and use class name for the appName.
serialPort = (SerialPort) portId.open(this.getClass().getName(), TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(BAUDRATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
ses.scheduleAtFixedRate(() -> write(status.generateJSON()), 5 * 1000, 10, TimeUnit.MILLISECONDS);
// add event listeners
serialPort.addEventListener(oEvent -> {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine = input.readLine();
debugArea.append(inputLine + "\n");
debugArea.setCaretPosition(debugArea.getDocument().getLength());
} catch (Exception ex) {
//Logger.error(ex);
}
}
});
serialPort.notifyOnDataAvailable(true);
refreshButton.setEnabled(false);
comPorts.setEnabled(false);
startServerButton.setEnabled(true);
connectButton.setText("Disconnect");
} catch (Exception ex) {
Logger.error(ex);
}
} else {
close();
serialPort = null;
refreshButton.setEnabled(true);
comPorts.setEnabled(true);
startServerButton.setEnabled(false);
connectButton.setText("Connect");
ses.shutdown();
// TODO: Stop Server
}
}
});
sendButton.addActionListener(e -> {
write(txText.getText());
txText.setText("");
});
updateButton.addActionListener(e -> {
status.setRpm(rpmSlider.getValue());
status.setKmh(kmhSlider.getValue());
status.setFuel((Integer) fuelSpinner.getValue());
status.setFogbeam(fogBeamCheckBox.isSelected());
status.setHighbeam(highBeamCheckBox.isSelected());
status.setHandbrake(handbrakeCheckBox.isSelected());
status.setAbs(ABSCheckBox.isSelected());
status.setOil_pressure(oilPressureCheckBox.isSelected());
status.setTire_pressure(tirePressureCheckBox.isSelected());
status.setKupplung(kupplungCheckBox.isSelected());
status.setTrunk(openTrunkCheckBox.isSelected());
status.setBacklight(backlightCheckBox.isSelected());
status.setL_turn_signal(lTurnSignalCheckBox.isSelected());
status.setR_turn_signal(rTurnSignalCheckBox.isSelected());
status.setOffroad(offroadCheckBox.isSelected());
status.setWater_temp(waterTempCheckBox.isSelected());
status.setSeat_belt(seatBeltCheckBox.isSelected());
status.setBattery(lowVoltageCheckBox.isSelected());
status.setCheck_lamp(checkLampCheckBox.isSelected());
status.setDoors(openDoorsCheckBox.isSelected());
Logger.info(status.generateJSON());
Logger.info(status.generateJSON().getBytes().length);
});
}
public void write(String payload) {
if (serialPort != null) {
try {
output.write(payload.getBytes());
output.flush();
} catch (IOException e) {
Logger.error(e);
}
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
private void refreshPortList() {
DefaultListModel<String> model = new DefaultListModel<>();
comPorts.setModel(model);
listPorts().forEach(model::addElement);
}
private CommPortIdentifier getPortIDbyString(String port) {
CommPortIdentifier portID = null;
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while (portEnum.hasMoreElements()) {
CommPortIdentifier portIdentifier = portEnum.nextElement();
if (portIdentifier.getName().equals(port)) {
portID = portIdentifier;
break;
}
}
return portID;
}
private ArrayList<String> listPorts() {
ArrayList<String> ports = new ArrayList<>();
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while (portEnum.hasMoreElements()) {
CommPortIdentifier portIdentifier = portEnum.nextElement();
if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) ports.add(portIdentifier.getName());
}
return ports;
}
public static void infoBox(String infoMessage, String titleBar) {
JOptionPane.showMessageDialog(null, infoMessage, "INFO: " + titleBar, JOptionPane.INFORMATION_MESSAGE);
}
public static void errorBox(String errorMessage, String titleBar) {
JOptionPane.showMessageDialog(null, errorMessage, "ERROR: " + titleBar, JOptionPane.ERROR_MESSAGE);
}
}