commit 1f5cc164ce6a08abab880f549d4f7dc81620b87e Author: Gurkengewuerz Date: Mon Jan 8 22:25:17 2018 +0100 wip diff --git a/lib/darcula.jar b/lib/darcula.jar new file mode 100644 index 0000000..0bd5a3a Binary files /dev/null and b/lib/darcula.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bde65fe --- /dev/null +++ b/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + de.gurkengewuerz + serialinterface + 1.0-SNAPSHOT + + + + org.rxtx + rxtx + 2.1.7 + + + org.json + json + 20160810 + + + org.tinylog + tinylog + 1.3.2 + + + com.intellij + forms_rt + 7.0.3 + + + com.bulenkov + darcula + 1.0.0 + system + ${project.basedir}/lib/darcula.jar + + + + + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + 2.6 + + false + ${project.artifactId} + + + jar-with-dependencies + + + + + ${project.groupId}.${project.artifactId}.SerialInterface + + + + + + assamble + + single + + package + + + + + + \ No newline at end of file diff --git a/src/main/java/de/gurkengewuerz/serialinterface/DashboardStatus.java b/src/main/java/de/gurkengewuerz/serialinterface/DashboardStatus.java new file mode 100644 index 0000000..72d58b6 --- /dev/null +++ b/src/main/java/de/gurkengewuerz/serialinterface/DashboardStatus.java @@ -0,0 +1,140 @@ +package de.gurkengewuerz.serialinterface; + +import org.json.JSONObject; +import org.pmw.tinylog.Logger; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/** + * Created by gurkengewuerz.de on 08.01.2018. + */ +public class DashboardStatus { + + private int fuel = 100; + private int rpm = 0; + private int kmh = 0; + private boolean backlight = true; + private boolean fogbeam = false; + private boolean highbeam = false; + private boolean handbrake = false; + private boolean abs = false; + private boolean oil_pressure = false; + private boolean tire_pressure = false; + private boolean kupplung = false; + private boolean trunk = false; + private boolean l_turn_signal = false; + private boolean r_turn_signal = false; + private boolean offroad = false; + private boolean water_temp = false; + private boolean seat_belt = false; + private boolean battery = false; + private boolean check_lamp = false; + private boolean doors = false; + + public void setFuel(int fuel) { + this.fuel = fuel; + } + + public void setRpm(int rpm) { + this.rpm = rpm; + } + + public void setKmh(int kmh) { + this.kmh = kmh; + } + + public void setBacklight(boolean backlight) { + this.backlight = backlight; + } + + public void setFogbeam(boolean fogbeam) { + this.fogbeam = fogbeam; + } + + public void setHighbeam(boolean highbeam) { + this.highbeam = highbeam; + } + + public void setHandbrake(boolean handbrake) { + this.handbrake = handbrake; + } + + public void setAbs(boolean abs) { + this.abs = abs; + } + + public void setOil_pressure(boolean oil_pressure) { + this.oil_pressure = oil_pressure; + } + + public void setTire_pressure(boolean tire_pressure) { + this.tire_pressure = tire_pressure; + } + + public void setKupplung(boolean kupplung) { + this.kupplung = kupplung; + } + + public void setTrunk(boolean trunk) { + this.trunk = trunk; + } + + public void setL_turn_signal(boolean l_turn_signal) { + this.l_turn_signal = l_turn_signal; + } + + public void setR_turn_signal(boolean r_turn_signal) { + this.r_turn_signal = r_turn_signal; + } + + public void setOffroad(boolean offroad) { + this.offroad = offroad; + } + + public void setWater_temp(boolean water_temp) { + this.water_temp = water_temp; + } + + public void setSeat_belt(boolean seat_belt) { + this.seat_belt = seat_belt; + } + + public void setBattery(boolean battery) { + this.battery = battery; + } + + public void setCheck_lamp(boolean check_lamp) { + this.check_lamp = check_lamp; + } + + public void setDoors(boolean doors) { + this.doors = doors; + } + + public String generateJSON() { + JSONObject obj = new JSONObject(); + obj.put("kmh", kmh); + obj.put("rpm", rpm); + obj.put("fuel", fuel); + obj.put("backlight", backlight); + obj.put("l_turn_signal", l_turn_signal); + obj.put("r_turn_signal", r_turn_signal); + obj.put("offroad", offroad); + obj.put("water_temp", water_temp); + obj.put("seat_belt", seat_belt); + obj.put("battery", battery); + obj.put("check_lamp", check_lamp); + obj.put("doors", doors); + obj.put("fogbeam", fogbeam); + obj.put("highbeam", highbeam); + obj.put("handbrake", handbrake); + obj.put("abs", abs); + obj.put("oil_pressure", oil_pressure); + obj.put("tire_pressure", tire_pressure); + obj.put("kupplung", kupplung); + obj.put("trunk", trunk); + + return obj.toString(); + } +} diff --git a/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.form b/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.form new file mode 100644 index 0000000..4fe4536 --- /dev/null +++ b/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.form @@ -0,0 +1,390 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.java b/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.java new file mode 100644 index 0000000..da9d544 --- /dev/null +++ b/src/main/java/de/gurkengewuerz/serialinterface/SerialGUI.java @@ -0,0 +1,290 @@ +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 model = new DefaultListModel<>(); + comPorts.setModel(model); + + listPorts().forEach(model::addElement); + } + + private CommPortIdentifier getPortIDbyString(String port) { + CommPortIdentifier portID = null; + + java.util.Enumeration portEnum = CommPortIdentifier.getPortIdentifiers(); + while (portEnum.hasMoreElements()) { + CommPortIdentifier portIdentifier = portEnum.nextElement(); + if (portIdentifier.getName().equals(port)) { + portID = portIdentifier; + break; + } + } + + return portID; + } + + private ArrayList listPorts() { + ArrayList ports = new ArrayList<>(); + java.util.Enumeration 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); + } +} diff --git a/src/main/java/de/gurkengewuerz/serialinterface/SerialInterface.java b/src/main/java/de/gurkengewuerz/serialinterface/SerialInterface.java new file mode 100644 index 0000000..0ec6471 --- /dev/null +++ b/src/main/java/de/gurkengewuerz/serialinterface/SerialInterface.java @@ -0,0 +1,37 @@ +package de.gurkengewuerz.serialinterface; + +import com.bulenkov.darcula.DarculaLaf; + +import javax.swing.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +/** + * Created by gurkengewuerz.de on 08.01.2018. + */ +public class SerialInterface { + + public static void main(String... args) { + try { + UIManager.setLookAndFeel(new DarculaLaf()); + } catch (UnsupportedLookAndFeelException e) { + e.printStackTrace(); + } + + + JFrame frame = new JFrame("Serial Interface Manager"); + SerialGUI gui = new SerialGUI(); + frame.setContentPane(gui.mainPanel); + + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + gui.close(); + frame.dispose(); + } + }); + + frame.pack(); + frame.setVisible(true); + } +}