Explorar o código

Many small fixes

- Comment cleanup
- Temporary temperature calculation (avg. of CPU and GPU)
- setFanSpeed optimizations
- FanPanel indexes from 1-6
- Profile speed calculation fixed
- Customizable polling speed
Tankernn %!s(int64=8) %!d(string=hai) anos
pai
achega
cf03e55697

+ 17 - 16
src/eu/tankernn/grid/Fan.java

@@ -7,19 +7,18 @@ public class Fan {
 	private int rpm, index;
 	private GRID grid;
 	private FanSpeedProfile profile;
-	private int speed = 100;
+	private int speed = 0;
 
 	public Fan(GRID grid, int index) {
 		this.grid = grid;
 		this.index = index;
+		poll();
+		this.speed = (int) (100 * voltage / 12);
 	}
 
 	public void update(double temp, int minSpeed) {
-		if (profile != null)
-			this.speed = profile.getSpeedPercentage(temp);
-		if (this.speed < minSpeed)
-			this.speed = 0;
-		setFanSpeed(speed);
+		int calcSpeed = profile.getSpeedPercentage(temp);
+		setFanSpeed(calcSpeed < minSpeed ? 0 : calcSpeed);
 	}
 
 	public void poll() {
@@ -94,23 +93,28 @@ public class Fan {
 	 * converted to 4V the comma value of the commands are always rounded to .50
 	 * and .0
 	 * 
-	 * @param percent
+	 * @param newSpeed
 	 */
-	public void setFanSpeed(int percent) {
+	public void setFanSpeed(int newSpeed) {
+		if (newSpeed == speed)
+			return;
+		// Spin up to 100 during first tick after being turned off
+		if (speed == 0)
+			newSpeed = 100;
 		if (grid.getCommunicator().isConnected()) {
 			int firstByte, lastByte, wantedVoltage = 0;
 
 			// The voltages between 0 and 4 are not recognised by the grid so
 			// any voltage under 4 will still be 4 and from 0 it will be 0
-			if (percent <= 0) {
+			if (newSpeed <= 0) {
 				firstByte = 0;
 				lastByte = 0;
 
-			} else if (percent < 34) {
+			} else if (newSpeed < 34) {
 				firstByte = 4;
 				lastByte = 0;
 			} else {
-				wantedVoltage = (1200 * percent) / 100;
+				wantedVoltage = (1200 * newSpeed) / 100;
 				firstByte = wantedVoltage / 100;
 				lastByte = (wantedVoltage - (firstByte * 100));
 
@@ -120,17 +124,14 @@ public class Fan {
 					lastByte = 0x50;
 				}
 			}
-			
-			if (wantedVoltage == voltage)
-				return;
 
 			byte[] command = { 0x44, (byte) (index + 1), -64, 0x00, 0x00, (byte) firstByte, (byte) lastByte };
 
 			grid.getCommunicator().writeData(command);
-
+			speed = newSpeed;
 		}
 	}
-	
+
 	public void setProfile(FanSpeedProfile profile) {
 		this.profile = profile;
 	}

+ 12 - 11
src/eu/tankernn/grid/FanSpeedProfile.java

@@ -3,31 +3,32 @@ package eu.tankernn.grid;
 import java.util.Arrays;
 
 public class FanSpeedProfile {
-	public static final int MAX_TEMP = 80, MIN_TEMP = 30, STEPS = 5;
-	
+	public static final double MAX_TEMP = 80, MIN_TEMP = 30;
+	public static final int STEPS = 5;
+
 	public final String name;
 	public final int[] percentages;
-	
+
 	public FanSpeedProfile(String name, int[] percentages) {
 		this.name = name;
 		this.percentages = percentages;
 	}
-	
+
 	public int getSpeedPercentage(double temp) {
-		int stepSize = (MAX_TEMP - MIN_TEMP) / STEPS;
-		
-		int currentTemp = MIN_TEMP;
-		
+		double stepSize = (MAX_TEMP - MIN_TEMP) / (double) STEPS;
+
+		double currentTemp = MIN_TEMP;
+
 		for (int i : percentages) {
 			if (temp < currentTemp) {
 				return i;
 			}
 			currentTemp += stepSize;
 		}
-		
-		return 100;
+
+		return percentages[percentages.length - 1];
 	}
-	
+
 	@Override
 	public String toString() {
 		return name + ": " + Arrays.toString(percentages);

+ 9 - 2
src/eu/tankernn/grid/GridControl.java

@@ -11,6 +11,8 @@ import eu.tankernn.grid.model.ComputerModel;
 
 public class GridControl implements WindowListener, Runnable {
 	private Thread t;
+	
+	private int pollingSpeed = 500;
 
 	private ComputerModel model = new ComputerModel();
 
@@ -18,7 +20,7 @@ public class GridControl implements WindowListener, Runnable {
 
 	public GridControl(boolean gui) {
 		if (gui) {
-			frame = new GridControlPanel(model);
+			frame = new GridControlPanel(this, model);
 			frame.setResizable(true);
 			frame.pack();
 			frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
@@ -39,8 +41,9 @@ public class GridControl implements WindowListener, Runnable {
 
 			if (frame != null)
 				frame.updateProperties();
+			
 			try {
-				Thread.sleep(1000);
+				Thread.sleep(pollingSpeed);
 			} catch (InterruptedException ex) {
 				System.out.println("Thread was interrupted.");
 				return;
@@ -100,4 +103,8 @@ public class GridControl implements WindowListener, Runnable {
 
 	}
 
+	public void setPollingSpeed(int value) {
+		this.pollingSpeed = value;
+	}
+
 }

+ 8 - 4
src/eu/tankernn/grid/frame/FanPanel.java

@@ -1,6 +1,7 @@
 package eu.tankernn.grid.frame;
 
 import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
 import java.text.DecimalFormat;
 import java.util.List;
 
@@ -30,7 +31,7 @@ public class FanPanel extends JPanel {
 			profileBox.addItem(p);
 		this.fan = fan;
 
-		this.setBorder(new TitledBorder("Fan " + fan.getIndex()));
+		this.setBorder(new TitledBorder("Fan " + (fan.getIndex() + 1)));
 
 		this.setLayout(new GridLayout(4, 1));
 
@@ -39,9 +40,8 @@ public class FanPanel extends JPanel {
 		this.add(rpmLabel);
 		this.add(profileBox);
 
-		profileBox.addActionListener((e) -> {
-			fan.setProfile((FanSpeedProfile) profileBox.getSelectedItem());
-		});
+		profileBox.addActionListener(this::updateProfile);
+		this.updateProfile(null);
 	}
 
 	public void update() {
@@ -55,4 +55,8 @@ public class FanPanel extends JPanel {
 	public void addProfile(FanSpeedProfile p) {
 		profileBox.addItem(p);
 	}
+	
+	private void updateProfile(ActionEvent e) {
+		fan.setProfile((FanSpeedProfile) profileBox.getSelectedItem());
+	}
 }

+ 19 - 17
src/eu/tankernn/grid/frame/GridControlPanel.java

@@ -6,9 +6,7 @@ import java.awt.GridLayout;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.text.DecimalFormat;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
+import java.util.Arrays;
 
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
@@ -24,6 +22,7 @@ import javax.swing.border.TitledBorder;
 import javax.swing.event.ChangeEvent;
 
 import eu.tankernn.grid.FanSpeedProfile;
+import eu.tankernn.grid.GridControl;
 import eu.tankernn.grid.model.ComputerModel;
 
 public class GridControlPanel extends JFrame {
@@ -40,9 +39,9 @@ public class GridControlPanel extends JFrame {
 	private JMenuItem saveSettings = new JMenuItem("Save settings..."), addProfile = new JMenuItem("Add profile...");
 	
 	private FanPanel[] fanPanels;
-	private JPanel gridPanel = new JPanel(), infoPanel = new JPanel();
+	private JPanel serialPanel = new JPanel(), gridPanel = new JPanel(), infoPanel = new JPanel();
 
-	private JSpinner minSpeed = new JSpinner();
+	private JSpinner minSpeed = new JSpinner(new SpinnerNumberModel(30, 0, 100, 5)), pollingSpeed = new JSpinner(new SpinnerNumberModel(500, 100, 2000, 100));
 
 	private JComboBox<String> portMap = new JComboBox<>();
 
@@ -56,8 +55,6 @@ public class GridControlPanel extends JFrame {
 
 	private JLabel PowerLabel = new JLabel("Power");
 
-	private List<FanSpeedProfile> profiles;
-
 	private void setMinRPM(ChangeEvent event) {
 		getModel().setMinSpeed((int) minSpeed.getValue());
 	}
@@ -70,7 +67,7 @@ public class GridControlPanel extends JFrame {
 		getModel().setGrid(selectedPort);
 	}
 
-	public GridControlPanel(ComputerModel model) {
+	public GridControlPanel(GridControl control, ComputerModel model) {
 		setModel(model);
 		this.setLayout(new BorderLayout());
 		
@@ -80,13 +77,21 @@ public class GridControlPanel extends JFrame {
 		menuBar.add(profileMenu);
 		profileMenu.add(addProfile);
 		addProfile.addActionListener(e -> {
-			profiles.add(new ProfileEditor().editProfile(null));
+			FanSpeedProfile p = new ProfileEditor().editProfile(null);
+			model.addProfile(p);
+			Arrays.stream(fanPanels).forEach(f -> f.addProfile(p));
 		});
 		
 		this.setJMenuBar(this.menuBar);
+		
+		serialPanel.setLayout(new FlowLayout());
+		serialPanel.setBorder(new TitledBorder("Serial settings"));
+		serialPanel.add(labelledComponent("COM port: ", portMap));
+		serialPanel.add(labelledComponent("Polling speed: ", pollingSpeed));
+		this.add(serialPanel, BorderLayout.NORTH);
+		
 
-		profiles = generateProfiles();
-		fanPanels = model.getGrid().fanStream().map(f -> new FanPanel(f, profiles)).toArray(FanPanel[]::new);
+		fanPanels = model.getGrid().fanStream().map(f -> new FanPanel(f, model.getProfiles())).toArray(FanPanel[]::new);
 
 		gridPanel.setLayout(new GridLayout(3, 2));
 		for (FanPanel p : fanPanels)
@@ -95,7 +100,9 @@ public class GridControlPanel extends JFrame {
 		this.add(gridPanel, BorderLayout.CENTER);
 
 		minSpeed.addChangeListener(this::setMinRPM);
-		minSpeed.setModel(new SpinnerNumberModel(30, 0, 100, 5));
+		pollingSpeed.addChangeListener(e -> {
+			control.setPollingSpeed((int) pollingSpeed.getValue());
+		});
 		
 		infoPanel.setBorder(new TitledBorder("System info"));
 		infoPanel.setLayout(new GridLayout(3, 2));
@@ -113,7 +120,6 @@ public class GridControlPanel extends JFrame {
 				setPort(e);
 			}
 		});
-		this.add(labelledComponent("COM port: ", portMap), BorderLayout.NORTH);
 		
 		this.setTitle("JavaGridControl");
 	}
@@ -125,10 +131,6 @@ public class GridControlPanel extends JFrame {
 		return panel;
 	}
 
-	private List<FanSpeedProfile> generateProfiles() {
-		return IntStream.range(30 / 5, 100 / 5).map(i -> i * 5).mapToObj(i -> new FanSpeedProfile(i + "%", new int[] { i })).collect(Collectors.toList());
-	}
-
 	/**
 	 * This method sets the model for this controller. After the model is set
 	 * certain UI elements are updated Finally a pollAndCompute Thread is

+ 3 - 20
src/eu/tankernn/grid/model/Communicator.java

@@ -120,10 +120,6 @@ public class Communicator {
 		}
 	}
 
-	// what happens when data is received
-	// pre: serial event is triggered
-	// post: processing on the data it reads
-
 	/**
 	 * 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
@@ -138,33 +134,20 @@ public class Communicator {
 		try {
 			if (input.available() > 0) {
 				try {
-
 					buffer = (new byte[32]);
-
 					leng = input.read(buffer);
-
-					// Debug.
-					/*
-					 * System.out.println("Length: " + getLeng());
-					 * 
-					 * for (int itera = 0; itera < leng; itera++) {
-					 * System.out.println("byte " + itera + ": " +
-					 * Integer.toHexString(getBuffer(itera) & 0xFF)); }
-					 */
 				} catch (Exception e) {
-					logText = "Failed to read data. (" + e.toString() + ")";
-					System.out.println(logText);
+					System.out.println("Failed to read data. (" + e.toString() + ")");
 				}
 			} else {
-				logText = "Failed to read data. No data to read";
-				// System.out.println(logText);
+				System.out.println("Failed to read data. No data to read");
 			}
 
 		} catch (IOException e) {
 			logText = "Failed to read data. (" + e.toString() + ")";
 			System.out.println(logText);
 		}
-		// This prevents commands from being send too soon
+		// This prevents commands from being sent too soon
 		sleep(50);
 		return buffer;
 	}

+ 28 - 3
src/eu/tankernn/grid/model/ComputerModel.java

@@ -1,7 +1,13 @@
 package eu.tankernn.grid.model;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import eu.tankernn.grid.FanSpeedProfile;
 
 /**
  * This model contains two main data members as well as some data members used
@@ -23,12 +29,15 @@ public class ComputerModel {
 	 */
 	private int minSpeed = 30;
 
+	private List<FanSpeedProfile> profiles;
+
 	/**
 	 *
-	 * All members get initialised here.
+	 * All members get initialized here.
 	 */
 	public ComputerModel() {
 		grid = new GRID();
+		profiles = generateProfiles();
 
 		try {
 			sensor = new Sensor();
@@ -56,6 +65,10 @@ public class ComputerModel {
 			ex.printStackTrace();
 		}
 	}
+	
+	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));
+	}
 
 	/**
 	 *
@@ -110,11 +123,23 @@ public class ComputerModel {
 	 * @return The temperature used to calculate fan speeds.
 	 */
 	public double getTemp() {
-		// TODO Calculate temp based on CPU/GPU
-		return 0;
+		// TODO Make configurable
+		return (sensor.getCPUTemp() + sensor.getGPUTemp()) / 2;
 	}
 
 	public void saveSettings() {
 		// TODO Implement
 	}
+
+	public List<FanSpeedProfile> getProfiles() {
+		return profiles;
+	}
+
+	public void setProfiles(List<FanSpeedProfile> profiles) {
+		this.profiles = profiles;
+	}
+
+	public void addProfile(FanSpeedProfile profile) {
+		profiles.add(profile);
+	}
 }

+ 3 - 3
src/eu/tankernn/grid/model/GRID.java

@@ -28,10 +28,10 @@ public class GRID {
 	 * at the selected port
 	 */
 	public GRID() {
-		fans = IntStream.range(0, 6).mapToObj(i -> new Fan(this, i)).toArray(Fan[]::new);
-
 		communicator = new Communicator();
 		communicator.searchForPorts();
+		
+		fans = IntStream.range(0, 6).mapToObj(i -> new Fan(this, i)).toArray(Fan[]::new);
 	}
 
 	/**
@@ -50,7 +50,7 @@ public class GRID {
 	}
 
 	public double getTotalWattage() {
-		return Arrays.stream(fans).mapToDouble(Fan::getWattage).sum();
+		return fanStream().mapToDouble(Fan::getWattage).sum();
 	}
 
 	public void pollFans() {