Browse Source

Communicator refactoring

Moved and removed stuff from Communicator class.
Tankernn 3 years ago
parent
commit
4ec10a38c3

+ 2 - 1
.gitignore

@@ -1,5 +1,6 @@
 /target/
-*.class
+*.class
+*.json
 
 # Mobile Tools for Java (J2ME)
 .mtj.tmp/

+ 8 - 8
src/eu/tankernn/grid/Fan.java

@@ -2,17 +2,17 @@ package eu.tankernn.grid;
 
 import java.util.function.BiFunction;
 
-import eu.tankernn.grid.model.GRID;
+import eu.tankernn.grid.model.Communicator;
 
 public class Fan {
 	private double voltage, current;
 	private int rpm, index;
-	private GRID grid;
+	private Communicator communicator;
 	private FanSpeedProfile profile;
 	private int speed = 0;
 
-	public Fan(GRID grid, int index) {
-		this.grid = grid;
+	public Fan(Communicator communicator, int index) {
+		this.communicator = communicator;
 		this.index = index;
 		poll();
 		this.speed = (int) (100 * voltage / 12);
@@ -57,10 +57,10 @@ public class Fan {
 	}
 
 	private Double pollValue(byte commandByte, BiFunction<Integer, Integer, Double> resultConsumer) {
-		if (grid.getCommunicator().isConnected()) {
+		if (communicator.isConnected()) {
 			byte[] command = { commandByte, (byte) (index + 1) };
 
-			byte[] response = grid.getCommunicator().writeData(command);
+			byte[] response = communicator.writeData(command);
 
 			return resultConsumer.apply((response[response.length - 2] & 0xFF),
 					(response[response.length - 1] & 0xff));
@@ -84,7 +84,7 @@ public class Fan {
 		// Spin up to 100 during first tick after being turned off
 		else if (speed == 0)
 			newSpeed = 100;
-		if (grid.getCommunicator().isConnected()) {
+		if (communicator.isConnected()) {
 			int firstByte, lastByte, wantedVoltage = 0;
 
 			// The voltages between 0 and 4 are not recognised by the grid so
@@ -110,7 +110,7 @@ public class Fan {
 
 			byte[] command = { 0x44, (byte) (index + 1), -64, 0x00, 0x00, (byte) firstByte, (byte) lastByte };
 
-			grid.getCommunicator().writeData(command);
+			communicator.writeData(command);
 			speed = newSpeed;
 		}
 	}

+ 6 - 1
src/eu/tankernn/grid/GridControl.java

@@ -59,7 +59,7 @@ public class GridControl implements WindowListener, Runnable {
 		}
 		try (Reader reader = new FileReader(SETTINGS_PATH)) {
 			Settings settings = gson.fromJson(reader, Settings.class);
-			model.getGrid().getCommunicator().connect(settings.portname);
+			model.setGrid(settings.portname);
 			for (int i = 0; i < 6; i++)
 				model.getGrid().getFan(i).setProfile(model.getProfile(settings.fanProfiles[i]));
 			pollingSpeed = settings.pollingRate;
@@ -127,6 +127,7 @@ public class GridControl implements WindowListener, Runnable {
 	public void windowClosing(WindowEvent e) {
 		t.interrupt();
 		model.getGrid().disconnect();
+		saveSettings();
 		e.getWindow().dispose();
 	}
 
@@ -164,4 +165,8 @@ public class GridControl implements WindowListener, Runnable {
 		this.pollingSpeed = value;
 	}
 
+	public int getPollingSpeed() {
+		return pollingSpeed;
+	}
+
 }

+ 1 - 1
src/eu/tankernn/grid/frame/GridControlPanel.java

@@ -145,7 +145,7 @@ public class GridControlPanel extends JFrame {
 		this.model = model;
 
 		portMap.removeAllItems();
-		for (String key : model.getGrid().getCommunicator().getPortMap().keySet()) {
+		for (String key : model.getPortMap().keySet()) {
 			portMap.addItem(key);
 		}
 		

+ 30 - 74
src/eu/tankernn/grid/model/Communicator.java

@@ -5,89 +5,56 @@ import static java.lang.Thread.sleep;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.HashMap;
 
 import com.fazecast.jSerialComm.SerialPort;
 
 public class Communicator {
 
-	// for containing the ports that will be found
-	private SerialPort[] ports;
-	// map the port names to CommPortIdentifiers
-	private HashMap<String, SerialPort> portMap = new HashMap<>();
-	// this is the object that contains the opened port
 	private SerialPort serialPort = null;
 
-	// input and output streams for sending and receiving data
 	private InputStream input = null;
 	private OutputStream output = null;
 
-	/**
-	 *
-	 * This method searches for COM ports on the system and saves their
-	 * Identifier in the hashmap portMap with their name as key.
-	 * 
-	 */
-	public void searchForPorts() {
-		ports = SerialPort.getCommPorts();
-
-		for (SerialPort p : ports) {
-			portMap.put(p.getSystemPortName(), p);
-		}
-	}
-
-	// connect to the selected port in the combo box
-	// pre: ports are already found by using the searchForPorts method
-	// post: the connected comm port is stored in commPort, otherwise,
-	// an exception is generated
-
 	/**
 	 * This method opens the COM port with port parameters: Baudrate: 4800;
 	 * databits: 8; Stopbit: 1; parity: none;
 	 * 
 	 * @param selectedPort
 	 */
-	public void connect(String selectedPort) {
+	public void connect(SerialPort selectedPort) {
 		try {
-			serialPort = portMap.get(selectedPort);
+			serialPort = selectedPort;
 
+			// Open connection
 			serialPort.setBaudRate(4800);
 			serialPort.setNumDataBits(8);
 			serialPort.setNumStopBits(SerialPort.ONE_STOP_BIT);
 			serialPort.setParity(SerialPort.NO_PARITY);
 			serialPort.openPort();
-			initIOStream();
 
-			// logging
-			System.out.println(selectedPort + " opened successfully.");
+			input = serialPort.getInputStream();
+			output = serialPort.getOutputStream();
+
+			// Test connection (allow a few failures)
+			for (int i = 0; i < 8; i++) {
+				if (ping()) {
+					System.out.println(selectedPort.getSystemPortName() + " opened successfully.");
+					return;
+				}
+			}
+
+			System.err.println("Device did not respond correctly to ping.");
 		} catch (Exception e) {
-			System.out.println("Failed to open " + selectedPort + "(" + e.toString() + ")");
+			System.out.println("Failed to open " + selectedPort.getSystemPortName() + ".");
 			e.printStackTrace();
 		}
 	}
 
 	/**
-	 * This method initializes the serial IO stream, after the init is complete
-	 * the method sends an initialize command to the GRID+ controller
+	 * Sends test data to the device to check availability.
 	 * 
-	 * @return successful Boolean value which indicates whether the method was
-	 *         completed successfully
+	 * @return If the ping was successful (the device responded correctly)
 	 */
-	public void initIOStream() {
-		input = serialPort.getInputStream();
-		output = serialPort.getOutputStream();
-
-		knock();
-		if (!ping())
-			System.err.println("Device did not respond to ping.");
-	}
-
-	private void knock() {
-		for (int i = 0; i < 8; i++) {
-			ping();
-		}
-	}
-
 	private boolean ping() {
 		byte[] buffer = writeData(new byte[] { (byte) 0xc0 });
 		return buffer[0] == 0x21;
@@ -96,7 +63,6 @@ public class Communicator {
 	/**
 	 * This method disconnects the serial communication by first closing the
 	 * serialPort and then closing the IOStreams
-	 * 
 	 */
 	public void disconnect() {
 		if (serialPort == null || !serialPort.isOpen())
@@ -107,23 +73,17 @@ public class Communicator {
 			serialPort.closePort();
 			System.out.println("Disconnected.");
 		} catch (IOException e) {
-			System.err.println("Failed to close " + serialPort.getSystemPortName() + "(" + e.toString() + ")");
+			System.err.println("Failed to close " + serialPort.getSystemPortName() + ".");
+			e.printStackTrace();
 		}
 	}
 
 	/**
-	 * This method reads data from the input stream and puts it in a buffer
-	 * after the data is read the method waits 50 msec to make sure a new
-	 * command doesn't follow up to quickly This promotes stability in the
-	 * program.
-	 * 
-	 * @return
-	 * 
+	 * Reads a buffer of data from the device.
 	 * 
+	 * @return The data buffer
 	 */
-	private byte[] serialRead() throws InterruptedException {
-		// This prevents commands from being sent too soon
-		sleep(50);
+	private byte[] serialRead() {
 		try {
 			if (input.available() > 0) {
 				byte[] buffer = new byte[input.available()];
@@ -142,25 +102,21 @@ public class Communicator {
 	 * This method sends a byte array command over the serial communication
 	 * afterwards the method calls the read method
 	 * 
-	 * @param command
-	 *            an array of bytes as a command
+	 * @param command an array of bytes as a command
+	 * @return The response data from the device
 	 */
 	public byte[] writeData(byte[] command) {
 		try {
+			sleep(50);
 			output.write(command);
 			sleep(50);
 			return serialRead();
-		} catch (InterruptedException | IOException e) {
+		} catch (IOException e) {
 			System.out.println("Failed to write data. (" + e.toString() + ")");
-			return new byte[32];
+		} catch (InterruptedException e) {
+			// Just ignore
 		}
-	}
-
-	/**
-	 * @return the portMap
-	 */
-	public HashMap<String, SerialPort> getPortMap() {
-		return portMap;
+		return new byte[32];
 	}
 
 	public boolean isConnected() {

+ 35 - 8
src/eu/tankernn/grid/model/ComputerModel.java

@@ -1,6 +1,7 @@
 package eu.tankernn.grid.model;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -8,6 +9,8 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
+import com.fazecast.jSerialComm.SerialPort;
+
 import eu.tankernn.grid.FanSpeedProfile;
 
 /**
@@ -21,6 +24,11 @@ import eu.tankernn.grid.FanSpeedProfile;
  */
 public class ComputerModel {
 
+	/**
+	 * Maps port names to port objects
+	 */
+	private HashMap<String, SerialPort> portMap = new HashMap<>();
+
 	private Sensor sensor;
 	private GRID grid;
 
@@ -30,13 +38,15 @@ public class ComputerModel {
 	 */
 	private int minSpeed = 30;
 
-	private List<FanSpeedProfile> defaultProfiles, customProfiles = new ArrayList<>();
+	private List<FanSpeedProfile> defaultProfiles,
+			customProfiles = new ArrayList<>();
 
 	/**
 	 *
 	 * All members get initialized here.
 	 */
 	public ComputerModel() {
+		scanPorts();
 		grid = new GRID();
 		defaultProfiles = generateProfiles();
 
@@ -47,6 +57,18 @@ public class ComputerModel {
 		}
 	}
 
+	/**
+	 * This method searches for COM ports on the system and saves their
+	 * identifiers in the map with their name as key.
+	 */
+	public void scanPorts() {
+		SerialPort[] ports = SerialPort.getCommPorts();
+
+		for (SerialPort p : ports) {
+			portMap.put(p.getSystemPortName(), p);
+		}
+	}
+
 	/**
 	 *
 	 * Currently only the pollCPUPackageTemp method of the sensor object is
@@ -68,9 +90,7 @@ public class ComputerModel {
 	}
 
 	private List<FanSpeedProfile> generateProfiles() {
-		return IntStream.range(30 / 5, 100 / 5 + 1).map(i -> i * 5)
-				.mapToObj(i -> new FanSpeedProfile(i + "%", new int[] { i }))
-				.collect(Collectors.toCollection(ArrayList::new));
+		return IntStream.range(30 / 5, 100 / 5 + 1).map(i -> i * 5).mapToObj(i -> new FanSpeedProfile(i + "%", new int[] { i })).collect(Collectors.toCollection(ArrayList::new));
 	}
 
 	/**
@@ -107,11 +127,14 @@ public class ComputerModel {
 	/**
 	 * Connects to the GRID on the port specified.
 	 *
-	 * @param selectedPort
-	 *            The COM port the GRID controller is located at
+	 * @param selectedPort The COM port the GRID controller is located at
 	 */
 	public void setGrid(String selectedPort) {
-		grid.getCommunicator().connect(selectedPort);
+		if (!portMap.containsKey(selectedPort)) {
+			System.err.println("Unable to find port " + selectedPort + ".");
+			return;
+		}
+		grid.getCommunicator().connect(portMap.get(selectedPort));
 	}
 
 	public int getMinSpeed() {
@@ -122,6 +145,10 @@ public class ComputerModel {
 		this.minSpeed = minSpeed;
 	}
 
+	public HashMap<String, SerialPort> getPortMap() {
+		return portMap;
+	}
+
 	/**
 	 * 
 	 * @return The temperature used to calculate fan speeds.
@@ -134,7 +161,7 @@ public class ComputerModel {
 	public List<FanSpeedProfile> getProfiles() {
 		return Stream.concat(defaultProfiles.stream(), customProfiles.stream()).collect(Collectors.toList());
 	}
-	
+
 	public List<FanSpeedProfile> getCustomProfiles() {
 		return customProfiles;
 	}

+ 12 - 25
src/eu/tankernn/grid/model/GRID.java

@@ -7,40 +7,27 @@ import java.util.stream.Stream;
 import eu.tankernn.grid.Fan;
 
 /**
- *
- * This is a model for the GRID controller. This class uses the communicator
- * class to communicate to the GRID+ controller. To update their values they
- * each have poll functions instead of setters which send a command to the GRID
- * and read the response.
+ * This class uses the communicator class to communicate with the GRID+
+ * controller.
  * 
- * This class also has a boolean check that checks if the voltage command is the
- * same as the previous voltage command, this is to prevent pointless serial
- * communication.
- * 
- * @author Roel
+ * @author Frans
  */
 public class GRID {
-	private Communicator communicator;
-	private Fan[] fans;
-
-	/**
-	 * This constructor initiates all members afterwards it opens a communicator
-	 * at the selected port
-	 */
-	public GRID() {
-		communicator = new Communicator();
-		communicator.searchForPorts();
-		
-		fans = IntStream.range(0, 6).mapToObj(i -> new Fan(this, i)).toArray(Fan[]::new);
-	}
+	private Communicator communicator = new Communicator();
+	private Fan[] fans = IntStream.range(0, 6).mapToObj(i -> new Fan(communicator, i)).toArray(Fan[]::new);
 
 	/**
 	 * This method simply runs the disconnect method of the communicator.
 	 */
 	public void disconnect() {
-		getCommunicator().disconnect();
+		communicator.disconnect();
 	}
-
+	
+	/**
+	 * Gets the fan at the specified index.
+	 * @param index The fan index (0-5)
+	 * @return The fan object
+	 */
 	public Fan getFan(int index) {
 		return fans[index];
 	}

+ 1 - 2
src/eu/tankernn/grid/model/jWMI.java

@@ -143,8 +143,7 @@ public class jWMI {
      * @param envVarName the name of the env var to get
      * @return the value of the env var
      * @throws IOException 
-     * @throws InvalidNameException 
-     * @throws Exception if the given envVarName does not exist
+     * @throws InvalidNameException if the given envVarName does not exist
      *
      */
     private static String getEnvVar(String envVarName) throws IOException, InvalidNameException {