Browse Source

Renaming and lots of progress

Tankernn 8 years ago
parent
commit
ee659b7f08

+ 14 - 2
README.md

@@ -1,2 +1,14 @@
-# CamSucks
-An alternative control software for the NZXT GRID+ 
+# JavaGridControl
+A Java-based, open-source alternative to the default control software for the NZXT GRID+ and GRID+v2.
+
+## Credit
+- This project was originally a fork of ![RoelGo/CamSucks]()
+- The reverse engineering of the GRID+ communication was done by rizvanrp, their site is no longer available but here is a screenshot of their article on the GRID+. http://research.domaintools.com/research/screenshot-history/rizvanrp.com/#0
+- Some of the serial command codes were taken from akej74/grid-control
+- The sensor data on windows systems is read with the help of the jWMI class made by Henry Ranch @ http://henryranch.net
+- On windows systems, this class communicates with an external program called openhardwaremonitor @ http://openhardwaremonitor.org/
+
+##TODO
+- Make a config file to save user settings in.
+- Make it possible to control fans according to the temperatures of GPU, CPU or both.
+- Manual and profile-based fan speeds.

+ 0 - 133
src/camsucks/CAMSucks.java

@@ -1,133 +0,0 @@
-package camsucks;
-
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowListener;
-import java.io.IOException;
-
-import javax.imageio.ImageIO;
-import javax.swing.JFrame;
-
-/**
- * This Project aims to replace the default software made for the GRID+
- * Controller; CAM
- * <p>
- * Software used for this project
- * <p>
- * <ul>
- * <li>The reverse engineering of the GRID+ communication was done by rizvanrp,
- * their site is no longer available but here is a screenshot of their article
- * on the GRID+
- * http://research.domaintools.com/research/screenshot-history/rizvanrp.com/#0
- * <li>The aim is to be able to control the fan speed of the fans connected to a
- * GRID controller according to the temperature of the CPU Packages
- * <li>The project uses a Communicator class that has been created by Henry
- * Poon @ https://blog.henrypoon.com/
- * <li>With the help of this class the communication with the GRID+ controller
- * is handled
- * <li>The sensor data is read with the help of the jWMI class made by Henry
- * Ranch @ http://henryranch.net
- * <li>This class communicates with an external program called
- * openhardwaremonitor @ http://openhardwaremonitor.org/
- * </ul>
- * <p>
- * 
- * Currently monitoring is a bit bugged and is disabled by default but can be
- * turned on with a checkbox.
- * <p>
- * Future plans and TODOs:
- * <p>
- * <ul>
- * <li>Make it possible to control fans according to GPU or CPU or Both
- * temperatures (seems easy enough).
- * <li>Add Integral control to achieve full PI control (Before this can happen a
- * the time constant of the system must be defined reliably .
- * <li>Make program not crash after/during system sleep/hibernation.
- * <li>Find a way to compile program and not get security warnings (because of
- * the filewriter in the jWMI class).
- * <li>Make a config file to save user setting in.
- * </ul>
- * <p>
- * 
- * 
- * @author Roel
- */
-public class CAMSucks extends JFrame implements WindowListener {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-	
-	CAMSucksPanel panel = new CAMSucksPanel();
-
-	public CAMSucks() {
-		start();
-	}
-
-	public void start() {
-		this.add(panel);
-
-		setResizable(true);
-		setTitle("CAM Sucks!");
-		try {
-			setIconImage(ImageIO.read(getClass().getResourceAsStream("NoCAMIcon.jpg")));
-		} catch (IOException e1) {
-			e1.printStackTrace();
-		}
-		pack();
-		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-		addWindowListener(this);
-	}
-
-	/**
-	 * 
-	 * @param args the command line arguments
-	 */
-	public static void main(String[] args) {
-		CAMSucks cams = new CAMSucks();
-		cams.setVisible(true);
-	}
-
-	@Override
-	public void windowOpened(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void windowClosing(WindowEvent e) {
-		panel.getModel().getGrid().disconnect();
-		System.exit(0);
-	}
-
-	@Override
-	public void windowClosed(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void windowIconified(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void windowDeiconified(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void windowActivated(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-	@Override
-	public void windowDeactivated(WindowEvent e) {
-		// TODO Auto-generated method stub
-		
-	}
-
-}

+ 0 - 283
src/camsucks/CAMSucksPanel.java

@@ -1,283 +0,0 @@
-package camsucks;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.text.DecimalFormat;
-import java.util.Arrays;
-import java.util.stream.IntStream;
-
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JSlider;
-import javax.swing.JTable;
-import javax.swing.JTextField;
-
-import camsucks.model.ComputerModel;
-
-/**
- * This class is the controller of this Project. It initializes the Interactive
- * UI elements When its model is set it adds values to certain UI elements and
- * starts a pollAndCompute thread
- *
- *
- * @author Roel
- */
-public class CAMSucksPanel extends JPanel implements Runnable {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	private Thread t;
-
-	private ComputerModel model;
-
-	private String[] fanColumns = { "#", "Voltage", "Current", "RPM" };
-	private String[][] fanData;
-	private JTable fanTable = new JTable(fanData, fanColumns);
-
-	private JTextField targetRPM = new JTextField();
-
-	private JTextField targetCPUTemp = new JTextField();
-
-	private JTextField maxCPUTemp = new JTextField();
-
-	private JTextField targetGPUTemp = new JTextField();
-
-	private JTextField maxGPUTemp = new JTextField();
-
-	private JTextField minRPM = new JTextField();
-
-	private JComboBox<String> portMap = new JComboBox<>();
-
-	private JCheckBox manualCheck = new JCheckBox("Manual");
-
-	private JSlider manualSlider = new JSlider();
-
-	// private JTabbedPane MonitorTab;
-
-	private JLabel CPULabel = new JLabel("CPU preferred");
-
-	private JLabel CPULabelMax = new JLabel("CPU max");
-
-	private JLabel GPULabel = new JLabel("GPU preferred");
-
-	private JLabel GPULabelMax = new JLabel("GPU max");
-
-	private JLabel PowerLabel = new JLabel("Power");
-
-	private JLabel[] VoltageLabels;
-
-	private JLabel[] AMPLabels;
-
-	private JLabel[] RPMLabels;
-	// </editor-fold>
-
-	/*
-	 * private void closeMonitor(Event event) {
-	 * 
-	 * if (MonitorTab.isSelected() && monitorCheck.isSelected() ) {
-	 * //System.out.println(" opened monitor"); model.setExtraPoll(true);
-	 * 
-	 * } else {
-	 * 
-	 * //System.out.println(" open configure"); model.setExtraPoll(false); }
-	 * 
-	 * }
-	 */
-	private void setTargetRPM(ActionEvent event) {
-		double dTargetRPM = Double.parseDouble(targetRPM.getText());
-
-		getModel().setTargetRPM(dTargetRPM);
-
-		// System.out.println(model.getTargetRPM());
-	}
-
-	private void setTargetCPUTemp(ActionEvent event) {
-		double dTargetTemp = Double.parseDouble(targetCPUTemp.getText());
-
-		getModel().setTargetCPUTemp(dTargetTemp);
-
-		// System.out.println(model.getTargetTemp());
-	}
-
-	private void setTargetGPUTemp(ActionEvent event) {
-		double dTargetTemp = Double.parseDouble(targetGPUTemp.getText());
-
-		getModel().setTargetGPUTemp(dTargetTemp);
-
-		// System.out.println(model.getTargetTemp());
-	}
-
-	private void setMinRPM(ActionEvent event) {
-		int dMinRPM = Integer.parseInt(minRPM.getText());
-
-		getModel().setMinRPM(dMinRPM);
-
-		// System.out.println(model.getMaxTemp());
-	}
-
-	private void setMaxCPUTemp(ActionEvent event) {
-		double dMaxTemp = Double.parseDouble(maxCPUTemp.getText());
-
-		getModel().setMaxCPUTemp(dMaxTemp);
-
-		// System.out.println(model.getMaxTemp());
-	}
-
-	private void setMaxGPUTemp(ActionEvent event) {
-		double dMaxTemp = Double.parseDouble(maxGPUTemp.getText());
-
-		getModel().setMaxGPUTemp(dMaxTemp);
-
-		// System.out.println(model.getMaxTemp());
-	}
-
-	private void setPort(ItemEvent event) {
-
-		String selectedPort = (String) portMap.getSelectedItem();
-
-		getModel().getGrid().disconnect();
-
-		getModel().setGrid(selectedPort);
-
-	}
-
-	public CAMSucksPanel() {
-		VoltageLabels = IntStream.range(0, 6).mapToObj(i -> new JLabel("V " + i)).toArray(i -> new JLabel[i]);
-		AMPLabels = IntStream.range(0, 6).mapToObj(i -> new JLabel("AMP " + i)).toArray(i -> new JLabel[i]);
-		RPMLabels = IntStream.range(0, 6).mapToObj(i -> new JLabel("RPM " + i)).toArray(i -> new JLabel[i]);
-
-		for (JLabel l : VoltageLabels)
-			this.add(l);
-		for (JLabel l : AMPLabels)
-			this.add(l);
-		for (JLabel l : RPMLabels)
-			this.add(l);
-
-		this.add(fanTable);
-
-		// MonitorTab.setOnSelectionChanged(this::closeMonitor);
-
-		targetRPM.addActionListener(this::setTargetRPM);
-
-		targetCPUTemp.addActionListener(this::setTargetCPUTemp);
-
-		maxCPUTemp.addActionListener(this::setMaxCPUTemp);
-
-		targetGPUTemp.addActionListener(this::setTargetGPUTemp);
-
-		maxGPUTemp.addActionListener(this::setMaxGPUTemp);
-
-		minRPM.addActionListener(this::setMinRPM);
-
-		//manualCheck.addActionListener(this::setManual);
-
-		manualSlider.setMaximum(100);
-
-		manualSlider.setMinimum(0);
-
-//		manualSlider.addChangeListener(new ChangeListener() {
-//
-//			@Override
-//			public void stateChanged(ChangeEvent e) {
-//				manualSpeed(e);
-//			}
-//		});
-
-		portMap.addItemListener(new ItemListener() {
-
-			@Override
-			public void itemStateChanged(ItemEvent e) {
-				setPort(e);
-			}
-		});
-
-	}
-
-	/**
-	 * This method sets the model for this controller. After the model is set
-	 * certain UI elements are updated Finally a pollAndCompute Thread is
-	 * started
-	 *
-	 * @param model the model to set
-	 */
-	public void setModel(ComputerModel model) {
-		this.model = model;
-
-		portMap.removeAllItems();
-		for (String key : model.getGrid().getCommunicator().getPortMap().keySet()) {
-			portMap.addItem(key);
-		}
-
-		maxCPUTemp.setText(Double.toString(model.getMaxCPUTemp()));
-		maxGPUTemp.setText(Double.toString(model.getMaxGPUTemp()));
-
-		targetRPM.setText(Double.toString(model.getTargetRPM()));
-
-		targetCPUTemp.setText(Double.toString(model.getTargetCPUTemp()));
-		targetGPUTemp.setText(Double.toString(model.getTargetGPUTemp()));
-
-		minRPM.setText(Double.toString(model.getMinRPM()));
-
-		updateProperties();
-
-		t = new Thread(this);
-		t.setDaemon(true);
-		t.start();
-	}
-
-	/**
-	 * This method updates the values of some UI elements and binds properties
-	 * to others
-	 *
-	 */
-	public void updateProperties() {
-		DecimalFormat df = new DecimalFormat("#.##");
-
-		CPULabel.setText(df.format(getModel().getSensor().getCPUTemp()) + " °C");
-		PowerLabel.setText(df.format(getModel().getGrid().getTotalWattage()) + " W");
-		CPULabelMax.setText(df.format(getModel().getSensor().getCpuMax()) + " °C Max");
-		GPULabel.setText(df.format(getModel().getSensor().getGPUTemp()) + " °C");
-		GPULabelMax.setText(df.format(getModel().getSensor().getGpuMax()) + " °C Max");
-
-		String[] indices = IntStream.range(0, 6).mapToObj(Integer::toString).toArray(String[]::new);
-		String[] voltages = Arrays.stream(getModel().getGrid().getVoltage()).mapToObj(df::format).toArray(String[]::new);
-		String[] rpms = Arrays.stream(getModel().getGrid().getFanRPM()).mapToObj(df::format).toArray(String[]::new);
-		String[] currents = Arrays.stream(getModel().getGrid().getFanAMP()).mapToObj(df::format).toArray(String[]::new);
-
-		fanData = new String[][] { indices, voltages, rpms, currents };
-		System.out.println(Arrays.deepToString(fanData));
-	}
-
-	@Override
-	public void run() {
-		while (!t.isInterrupted()) {
-			getModel().poll();
-
-			new Thread((() -> {
-				updateProperties();
-			})).start();
-			
-			if (!getModel().isManual()) {
-				getModel().compute();
-			}
-
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException ex) {
-				System.out.println("Thread got interrupted");
-				return;
-			}
-		}
-
-	}
-
-	public ComputerModel getModel() {
-		return model;
-	}
-}

+ 0 - 262
src/camsucks/model/ComputerModel.java

@@ -1,262 +0,0 @@
-package camsucks.model;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This is the model of this project
- *
- * This model contains two main data members as well as some data members used
- * to configure the calculations and two checks
- *
- * Along with all the getters and setters this model has two methods used for
- * polling and calculating
- *
- * @author Roel
- */
-public class ComputerModel {
-
-	// The main components of the Computermodel
-	private Sensor sensor;
-	private GRID grid;
-
-	// The variables used to calculate the percentage to send
-	private double maxCPUTemp;
-	private double maxGPUTemp;
-	private double targetCPUTemp;
-	private double targetGPUTemp;
-	private double targetRPM;
-	// a global minimum percentage, this is used to prevent the controller to
-	// constantly turn the fans on and off
-	private int minRPM;
-
-	// Boolean Checks used to know whether to run certain pieces of code
-	private boolean manual;
-
-	/**
-	 *
-	 * All members get initialised here.
-	 *
-	 * @param selectedPort
-	 */
-	public ComputerModel(String selectedPort) {
-		targetRPM = 35;
-		targetCPUTemp = 50;
-		maxCPUTemp = 80;
-		targetGPUTemp = 50;
-		maxGPUTemp = 80;
-		minRPM = 20;
-		manual = false;
-
-		grid = new GRID(selectedPort);
-
-		try {
-			sensor = new Sensor();
-		} catch (Exception ex) {
-			Logger.getLogger(ComputerModel.class.getName()).log(Level.SEVERE, null, ex);
-		}
-	}
-
-	/**
-	 *
-	 * Currently only the pollCPUPackageTemp method of the sensor object is
-	 * called This can change in the future
-	 *
-	 */
-	public void poll() {
-		System.out.println("Polling...");
-
-		if (!getGrid().isSame()) {
-			for (int i = 0; i < 6; i++) {
-				getGrid().pollVoltage(i);
-				getGrid().pollFanAMP(i);
-				getGrid().pollFanRPM(i);
-			}
-		}
-
-		try {
-			getSensor().pollCPUTemp();
-			getSensor().pollCPUMax();
-			getSensor().pollGPUTemp();
-			getSensor().pollGPUMax();
-
-		} catch (Exception ex) {
-			System.out.println("Polling Failed");
-			ex.printStackTrace();
-		}
-
-	}
-
-	/**
-	 *
-	 * In this method the percentage to sent is computed. The calculation aims
-	 * to act as a proportional controller. A later step could be to add an
-	 * integral controller to the calculation to get a better calculated fan
-	 * curve
-	 *
-	 */
-	public void compute() {
-		double currentCPUTemp = getSensor().getCPUTemp();
-
-		double CPUerror = (currentCPUTemp - getTargetCPUTemp());
-
-		double CPUkFactor = ((100 - getTargetRPM()) / (getMaxCPUTemp() - getTargetCPUTemp()));
-
-		int tempCPUPercentage = (int) (getTargetRPM() + (CPUkFactor * CPUerror));
-
-		if (tempCPUPercentage < minRPM) {
-			tempCPUPercentage = minRPM;
-		}
-
-		double currentGPUTemp = getSensor().getGPUTemp();
-
-		double GPUerror = (currentGPUTemp - getTargetGPUTemp());
-
-		double GPUkFactor = ((100 - getTargetRPM()) / (getMaxGPUTemp() - getTargetGPUTemp()));
-
-		int tempGPUPercentage = (int) (getTargetRPM() + (GPUkFactor * GPUerror));
-
-		if (tempGPUPercentage < minRPM) {
-			tempGPUPercentage = minRPM;
-		}
-		
-		updateFanSpeed(Math.max(tempCPUPercentage, tempGPUPercentage));
-	}
-
-	public void updateFanSpeed(int percentage) {
-		for (int i = 0; i < 6; i++)
-			getGrid().setFanSpeed(i, percentage);
-	}
-
-	/**
-	 * A getter for the Sensor Object to make the methods of the object
-	 * available
-	 *
-	 * @return the sensor
-	 */
-	public Sensor getSensor() {
-		return sensor;
-	}
-
-	/**
-	 * A getter for the GRID Object to make the methods of the object available
-	 *
-	 * @return the grid
-	 */
-	public GRID getGrid() {
-		return grid;
-	}
-
-	/**
-	 * This setter overwrites the old GRID with a new Object with the
-	 * selectedport as the COM port to connect to
-	 *
-	 * @param selectedPort The com port the GRID controller is located at
-	 */
-	public void setGrid(String selectedPort) {
-		grid = new GRID(selectedPort);
-	}
-
-	/**
-	 *
-	 * @return the targetRPM
-	 */
-	public double getTargetRPM() {
-		return targetRPM;
-	}
-
-	/**
-	 * @param targetRPM the targetRPM to set
-	 */
-	public void setTargetRPM(double targetRPM) {
-		this.targetRPM = targetRPM;
-	}
-
-	/**
-	 * @return the targetTemp
-	 */
-	public double getTargetCPUTemp() {
-		return targetCPUTemp;
-	}
-
-	/**
-	 * @param targetTemp the targetTemp to set
-	 */
-	public void setTargetCPUTemp(double targetTemp) {
-		this.targetCPUTemp = targetTemp;
-	}
-
-	/**
-	 * @return the maxTemp
-	 */
-	public double getMaxCPUTemp() {
-		return maxCPUTemp;
-	}
-
-	/**
-	 * @param maxTemp the maxTemp to set
-	 */
-	public void setMaxCPUTemp(double maxTemp) {
-		this.maxCPUTemp = maxTemp;
-	}
-
-	/**
-	 * @return the targetTemp
-	 */
-	public double getTargetGPUTemp() {
-		return targetGPUTemp;
-	}
-
-	/**
-	 * @param targetTemp the targetTemp to set
-	 */
-	public void setTargetGPUTemp(double targetTemp) {
-		this.targetGPUTemp = targetTemp;
-	}
-
-	/**
-	 * @return the maxTemp
-	 */
-	public double getMaxGPUTemp() {
-		return maxGPUTemp;
-	}
-
-	/**
-	 * @param maxTemp the maxTemp to set
-	 */
-	public void setMaxGPUTemp(double maxTemp) {
-		this.maxGPUTemp = maxTemp;
-	}
-
-	/**
-	 * A check to see whether the percentage to send is manually set or has to
-	 * be calculated
-	 *
-	 * @return the manual
-	 */
-	public boolean isManual() {
-		return manual;
-	}
-
-	/**
-	 * @param manual the manual to set
-	 */
-	public void setManual(boolean manual) {
-		this.manual = manual;
-	}
-
-	/**
-	 * @return the minRPM
-	 */
-	public double getMinRPM() {
-		return minRPM;
-	}
-
-	/**
-	 *
-	 * @param minRPM
-	 */
-	public void setMinRPM(int minRPM) {
-		this.minRPM = minRPM;
-	}
-}

+ 0 - 248
src/camsucks/model/GRID.java

@@ -1,248 +0,0 @@
-package camsucks.model;
-
-/**
- *
- * This is a model for the GRID controller This class uses the communicator
- * class to communicate to the GRID+ controller This class contains a few data
- * members that contain data that can be gathered from the GRID+ This class has
- * some getters for these members To update their values they each have poll
- * functions instead of setters which send a command to the GRID and read the
- * response To set the fan speed this class has a setFanSpeed method which sets
- * the voltage of the GRID+ according to a percentage input.
- * 
- * 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 This check also has a getter to make it usable for other
- * classes
- * 
- * @author Roel
- */
-public class GRID {
-
-	private double[] voltage = new double[6];
-
-	private int[] fanRPM = new int[6];
-
-	private double[] fanAMP = new double[6];
-
-	private double totalWattage = 0;
-
-	private byte[] lastCommand = new byte[6];
-
-	private Communicator communicator;
-
-	private boolean same;
-
-	/**
-	 * This constructor initialises all members afterwards it opens a
-	 * communicator at the selected port
-	 * 
-	 * @param selectedPort the com port to connect to
-	 */
-	public GRID(String selectedPort) {
-		lastCommand[4] = 1;
-		lastCommand[5] = 2;
-
-		communicator = new Communicator();
-		communicator.searchForPorts();
-		communicator.connect(selectedPort);
-	}
-
-	/**
-	 * This method simply runs the disconnect method of the communicator
-	 */
-	public void disconnect() {
-		getCommunicator().disconnect();
-	}
-
-	/**
-	 * @return the voltage
-	 */
-	public double[] getVoltage() {
-		return voltage;
-	}
-
-	/**
-	 * @return the fanRPM
-	 */
-	public int[] getFanRPM() {
-		return fanRPM;
-	}
-
-	/**
-	 * @return the fanAMP
-	 */
-	public double[] getFanAMP() {
-		return fanAMP;
-	}
-
-	/**
-	 * @return the voltage
-	 */
-	public double getVoltage(int fan) {
-		return voltage[fan];
-	}
-
-	/**
-	 * @param fan the index of the fan
-	 * @return the fanRPM of the fan with index fan
-	 */
-	public int getRPM(int fan) {
-		return fanRPM[fan];
-	}
-
-	/**
-	 * @param fan the index of the fan
-	 * @return the fanAMP of the fan with index fan
-	 */
-	public double getAMP(int fan) {
-		return fanAMP[fan];
-	}
-
-	/**
-	 * This method polls the Fan Amperage of the fan with index fan it first
-	 * send the poll command and reads the byte data from the buffer this byte
-	 * data is then converted to a double
-	 * 
-	 * @param fan the index of the fan
-	 */
-	public void pollFanAMP(int fan) {
-		if (getCommunicator().isConnected()) {
-			// 0x85 = -123
-			byte[] command = { -123, (byte) (fan + 1) };
-
-			getCommunicator().writeData(command);
-
-			fanAMP[fan] = (double) (((int) getCommunicator().getSecondToLast() & 0xFF) + (((double) (getCommunicator().getlast() & 0xff) / 100)));
-		} else {
-			fanAMP[fan] = 0d;
-		}
-	}
-
-	/**
-	 * This method polls the Fan RPM of the fan with index fan it first send the
-	 * poll command and reads the byte data from the buffer this byte data is
-	 * then converted to an int
-	 * 
-	 * @param fan the index of the fan
-	 */
-	public void pollFanRPM(int fan) {
-		if (getCommunicator().isConnected()) {
-			// 0x8A = -118
-			byte[] command = { -118, (byte) (fan + 1) };
-
-			getCommunicator().writeData(command);
-
-			fanRPM[fan] = (((int) (getCommunicator().getSecondToLast() & 0xFF) << 8) | ((getCommunicator().getlast() & 0xFF)));
-		} else {
-			fanRPM[fan] = 0;
-
-		}
-	}
-
-	/**
-	 * This method polls the voltage of all the fans it first send the poll
-	 * command and reads the byte data from the buffer this byte data is then
-	 * converted to a double
-	 */
-	public void pollVoltage(int fan) {
-		if (getCommunicator().isConnected()) {
-			// 0x84 = -124
-			byte[] command = { -124, (byte) (fan + 1) };
-
-			getCommunicator().writeData(command);
-
-			voltage[fan] = (double) (((int) getCommunicator().getSecondToLast() & 0xFF) + (((double) (getCommunicator().getlast() & 0xff) / 100)));
-		} else {
-			voltage[fan] = 0d;
-		}
-	}
-
-	/**
-	 * this method calculates the voltage to set the fans at according to a
-	 * percentage of the maximum voltage 12V then it send the command to set
-	 * that voltage the voltages between 0 and 4 are not recognised so these are
-	 * converted to 4V the comma value of the commands are always rounded to .50
-	 * and .0
-	 * 
-	 * @param percent
-	 */
-	public void setFanSpeed(int fan, int percent) {
-
-		if (getCommunicator().isConnected()) {
-			int firstByte, lastByte, wantedVoltage;
-
-			// 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) {
-				firstByte = 0;
-				lastByte = 0;
-
-			} else if (percent < 34) {
-				firstByte = 4;
-				lastByte = 0;
-			} else {
-
-				wantedVoltage = (1200 * percent) / 100;
-				firstByte = wantedVoltage / 100;
-				lastByte = (wantedVoltage - (firstByte * 100));
-
-				if (lastByte < 50) {
-					lastByte = 0x00;
-				} else {
-					lastByte = 0x50;
-				}
-
-			}
-
-			byte[] command = { 0x44, (byte) (fan + 1), -64, 0x00, 0x00, (byte) firstByte, (byte) lastByte };
-
-			if ((lastCommand[5] != command[5] || lastCommand[6] != command[6])) {
-				getCommunicator().writeData(command);
-				lastCommand = command;
-				setSame(false);
-			} else {
-				setSame(true);
-			}
-
-		}
-
-	}
-
-	/**
-	 * @return the communicator
-	 */
-	public Communicator getCommunicator() {
-		return communicator;
-	}
-
-	/**
-	 * 
-	 * @return A boolean value that is true if the last command is the same as
-	 *         the new
-	 */
-	public boolean isSame() {
-		return same;
-	}
-
-	/**
-	 * @param same boolean value that is true if the last command is the same as
-	 *        the new
-	 */
-	public void setSame(boolean same) {
-		this.same = same;
-	}
-
-	/**
-	 * @return the totalWattage
-	 */
-	public double getTotalWattage() {
-		totalWattage = 0;
-		for (int i = 0; i < fanAMP.length; i++) {
-			totalWattage += getAMP(i) * getVoltage(i);
-		}
-
-		return totalWattage;
-	}
-
-}

+ 162 - 0
src/eu/tankernn/grid/Fan.java

@@ -0,0 +1,162 @@
+package eu.tankernn.grid;
+
+import eu.tankernn.grid.model.GRID;
+
+public class Fan {
+	private double voltage, current;
+	private int rpm, index;
+	private GRID grid;
+	private FanSpeedProfile profile;
+	private int speed;
+
+	public Fan(GRID grid, int index) {
+		this.grid = grid;
+		this.index = index;
+	}
+
+	public void update(double temp) {
+		if (profile != null)
+			this.speed = profile.getSpeedPercentage(temp);
+		
+		setFanSpeed(speed);
+	}
+
+	public void poll() {
+		pollFanAMP();
+		pollFanRPM();
+		pollVoltage();
+	}
+
+	/**
+	 * This method polls the Fan Amperage of the fan with index fan it first
+	 * send the poll command and reads the byte data from the buffer this byte
+	 * data is then converted to a double
+	 * 
+	 * @param fan the index of the fan
+	 */
+	public void pollFanAMP() {
+		if (grid.getCommunicator().isConnected()) {
+			// 0x85 = -123
+			byte[] command = { -123, (byte) (index + 1) };
+
+			grid.getCommunicator().writeData(command);
+
+			current = (double) (((int) grid.getCommunicator().getSecondToLast() & 0xFF) + (((double) (grid.getCommunicator().getlast() & 0xff) / 100)));
+		} else {
+			current = 0d;
+		}
+	}
+
+	/**
+	 * This method polls the Fan RPM of the fan with index fan it first send the
+	 * poll command and reads the byte data from the buffer this byte data is
+	 * then converted to an int
+	 * 
+	 * @param fan the index of the fan
+	 */
+	public void pollFanRPM() {
+		if (grid.getCommunicator().isConnected()) {
+			// 0x8A = -118
+			byte[] command = { -118, (byte) (index + 1) };
+
+			grid.getCommunicator().writeData(command);
+
+			rpm = (((int) (grid.getCommunicator().getSecondToLast() & 0xFF) << 8) | ((grid.getCommunicator().getlast() & 0xFF)));
+		} else {
+			rpm = 0;
+
+		}
+	}
+
+	/**
+	 * This method polls the voltage of all the fans it first send the poll
+	 * command and reads the byte data from the buffer this byte data is then
+	 * converted to a double
+	 */
+	public void pollVoltage() {
+		if (grid.getCommunicator().isConnected()) {
+			// 0x84 = -124
+			byte[] command = { -124, (byte) (index + 1) };
+
+			grid.getCommunicator().writeData(command);
+
+			voltage = (double) (((int) grid.getCommunicator().getSecondToLast() & 0xFF) + (((double) (grid.getCommunicator().getlast() & 0xff) / 100)));
+		} else {
+			voltage = 0d;
+		}
+	}
+
+	/**
+	 * this method calculates the voltage to set the fans at according to a
+	 * percentage of the maximum voltage 12V then it send the command to set
+	 * that voltage the voltages between 0 and 4 are not recognised so these are
+	 * converted to 4V the comma value of the commands are always rounded to .50
+	 * and .0
+	 * 
+	 * @param percent
+	 */
+	public void setFanSpeed(int percent) {
+		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) {
+				firstByte = 0;
+				lastByte = 0;
+
+			} else if (percent < 34) {
+				firstByte = 4;
+				lastByte = 0;
+			} else {
+				wantedVoltage = (1200 * percent) / 100;
+				firstByte = wantedVoltage / 100;
+				lastByte = (wantedVoltage - (firstByte * 100));
+
+				if (lastByte < 50) {
+					lastByte = 0x00;
+				} else {
+					lastByte = 0x50;
+				}
+			}
+			
+			if (wantedVoltage == voltage)
+				return;
+
+			byte[] command = { 0x44, (byte) (index + 1), -64, 0x00, 0x00, (byte) firstByte, (byte) lastByte };
+
+			grid.getCommunicator().writeData(command);
+
+		}
+
+	}
+
+	/**
+	 * @return the voltage
+	 */
+	public double getVoltage() {
+		return voltage;
+	}
+
+	/**
+	 * @return the fanRPM
+	 */
+	public int getRPM() {
+		return rpm;
+	}
+
+	/**
+	 * @return the fanAMP
+	 */
+	public double getAMP() {
+		return current;
+	}
+
+	public double getWattage() {
+		return voltage * current;
+	}
+
+	public int getIndex() {
+		return index;
+	}
+}

+ 33 - 0
src/eu/tankernn/grid/FanPanel.java

@@ -0,0 +1,33 @@
+package eu.tankernn.grid;
+
+import java.text.DecimalFormat;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+public class FanPanel extends JPanel {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	private Fan fan;
+	
+	private JLabel voltageLabel, currentLabel, rpmLabel;
+
+	public FanPanel(Fan fan) {
+		this.fan = fan;
+		
+		this.setBorder(new TitledBorder("Fan " + fan.getIndex()));
+	}
+	
+	public void update() {
+		DecimalFormat df = new DecimalFormat("#.##");
+		
+		voltageLabel.setText("Voltage: " + df.format(fan.getVoltage()) + "V");
+		currentLabel.setText("Current: " + df.format(fan.getAMP()) + "A");
+		rpmLabel.setText("Speed: " + df.format(fan.getRPM()) + "RPM");
+	}
+}

+ 22 - 0
src/eu/tankernn/grid/FanSpeedProfile.java

@@ -0,0 +1,22 @@
+package eu.tankernn.grid;
+
+public class FanSpeedProfile {
+	public static final int MAX_TEMP = 80, MIN_TEMP = 30, STEPS = 5;
+	
+	private int[] percentages = new int[STEPS];
+	
+	public int getSpeedPercentage(double temp) {
+		int stepSize = (MAX_TEMP - MIN_TEMP) / STEPS;
+		
+		int currentTemp = MIN_TEMP;
+		
+		for (int i : percentages) {
+			if (temp < currentTemp) {
+				return i;
+			}
+			currentTemp += stepSize;
+		}
+		
+		return 100;
+	}
+}

+ 81 - 0
src/eu/tankernn/grid/GridControl.java

@@ -0,0 +1,81 @@
+package eu.tankernn.grid;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+
+import javax.swing.JFrame;
+
+import eu.tankernn.grid.model.ComputerModel;
+
+public class GridControl extends JFrame implements WindowListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	GridControlPanel panel = new GridControlPanel();
+	ComputerModel model = new ComputerModel();
+
+	public GridControl() {
+		this.add(panel);
+		panel.setModel(model);
+		setResizable(true);
+		setTitle("JavaGridControl");
+		pack();
+		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+		addWindowListener(this);
+	}
+
+	/**
+	 * 
+	 * @param args the command line arguments
+	 */
+	public static void main(String[] args) {
+		GridControl cams = new GridControl();
+		cams.setVisible(true);
+	}
+
+	@Override
+	public void windowOpened(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void windowClosing(WindowEvent e) {
+		panel.getModel().getGrid().disconnect();
+		System.exit(0);
+	}
+
+	@Override
+	public void windowClosed(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void windowIconified(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void windowDeiconified(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void windowActivated(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void windowDeactivated(WindowEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

+ 147 - 0
src/eu/tankernn/grid/GridControlPanel.java

@@ -0,0 +1,147 @@
+package eu.tankernn.grid;
+
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.text.DecimalFormat;
+
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JTextField;
+
+import eu.tankernn.grid.model.ComputerModel;
+
+public class GridControlPanel extends JPanel implements Runnable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private Thread t;
+
+	private ComputerModel model;
+
+	private FanPanel[] fanPanels;
+
+	private JTextField minRPM = new JTextField();
+
+	private JComboBox<String> portMap = new JComboBox<>();
+
+	private JSlider manualSlider = new JSlider();
+
+	private JLabel CPULabel = new JLabel("CPU preferred");
+
+	private JLabel CPULabelMax = new JLabel("CPU max");
+
+	private JLabel GPULabel = new JLabel("GPU preferred");
+
+	private JLabel GPULabelMax = new JLabel("GPU max");
+
+	private JLabel PowerLabel = new JLabel("Power");
+
+	private void setMinRPM(ActionEvent event) {
+		getModel().setMinRPM(Integer.parseInt(minRPM.getText()));
+	}
+
+	private void setPort(ItemEvent event) {
+		String selectedPort = (String) portMap.getSelectedItem();
+
+		getModel().getGrid().disconnect();
+
+		getModel().setGrid(selectedPort);
+	}
+
+	public GridControlPanel() {
+		this.setLayout(new GridLayout(3, 2));
+
+		for (FanPanel p : fanPanels)
+			this.add(p);
+
+		minRPM.addActionListener(this::setMinRPM);
+
+		manualSlider.setMaximum(100);
+
+		manualSlider.setMinimum(0);
+
+		// manualSlider.addChangeListener(new ChangeListener() {
+		//
+		// @Override
+		// public void stateChanged(ChangeEvent e) {
+		// manualSpeed(e);
+		// }
+		// });
+
+		portMap.addItemListener(new ItemListener() {
+
+			@Override
+			public void itemStateChanged(ItemEvent e) {
+				setPort(e);
+			}
+		});
+
+	}
+
+	/**
+	 * This method sets the model for this controller. After the model is set
+	 * certain UI elements are updated Finally a pollAndCompute Thread is
+	 * started
+	 *
+	 * @param model the model to set
+	 */
+	public void setModel(ComputerModel model) {
+		this.model = model;
+
+		portMap.removeAllItems();
+		for (String key : model.getGrid().getCommunicator().getPortMap().keySet()) {
+			portMap.addItem(key);
+		}
+
+		updateProperties();
+
+		t = new Thread(this);
+		t.setDaemon(true);
+		t.start();
+	}
+
+	/**
+	 * This method updates the values of some UI elements and binds properties
+	 * to others
+	 *
+	 */
+	public void updateProperties() {
+		DecimalFormat df = new DecimalFormat("#.##");
+
+		CPULabel.setText(df.format(getModel().getSensor().getCPUTemp()) + " °C");
+		PowerLabel.setText(df.format(getModel().getGrid().getTotalWattage()) + " W");
+		CPULabelMax.setText(df.format(getModel().getSensor().getCpuMax()) + " °C Max");
+		GPULabel.setText(df.format(getModel().getSensor().getGPUTemp()) + " °C");
+		GPULabelMax.setText(df.format(getModel().getSensor().getGpuMax()) + " °C Max");
+	}
+
+	@Override
+	public void run() {
+		while (!t.isInterrupted()) {
+			model.poll();
+
+			updateProperties();
+
+			getModel().compute();
+
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException ex) {
+				System.out.println("Thread was interrupted.");
+				return;
+			}
+		}
+
+	}
+
+	public ComputerModel getModel() {
+		return model;
+	}
+}

+ 9 - 44
src/camsucks/model/Communicator.java → src/eu/tankernn/grid/model/Communicator.java

@@ -1,4 +1,4 @@
-package camsucks.model;
+package eu.tankernn.grid.model;
 
 import static java.lang.Thread.sleep;
 
@@ -9,18 +9,6 @@ import java.util.HashMap;
 
 import com.fazecast.jSerialComm.SerialPort;
 
-/**
- * This class communicates with a serial com device
- * 
- * @author Henry Poon @ https://blog.henrypoon.com/ Changes by Roel: Removed all
- *         references to the GUI class from Henry Poon's original project.
- *         Changed the event based serial read to a synchronised read after each
- *         write. Added a Buffer for the serial read so that the read data can
- *         easily be accessed by other classes Completely rewritten the
- *         writeData method so that it works with the GRID+ controller Added
- *         some getters and setters for the buffer added a getter for the
- *         portMap so that the controller and view can access it
- */
 public class Communicator {
 
 	// for containing the ports that will be found
@@ -34,14 +22,6 @@ public class Communicator {
 	private InputStream input = null;
 	private OutputStream output = null;
 
-	// the timeout value for connecting with the port
-	final static int TIMEOUT = 2000;
-
-	// some ascii values for for certain things
-	final static int SPACE_ASCII = 32;
-	final static int DASH_ASCII = 45;
-	final static int NEW_LINE_ASCII = 10;
-
 	// Buffer
 	private int leng;
 	private byte[] buffer;
@@ -49,10 +29,6 @@ public class Communicator {
 	// a string for recording what goes on in the program
 	String logText = "";
 
-	// search for all the serial ports
-	// pre: none
-	// post: adds all the found ports to a combo box on the GUI
-
 	/**
 	 *
 	 * This method searches for COM ports on the system and saves their
@@ -75,10 +51,10 @@ public class Communicator {
 	/**
 	 * This method opens the COM port with port parameters: Baudrate: 4800;
 	 * databits: 8; Stopbit: 1; parity: none;
-	 * @param selectedPort 
+	 * 
+	 * @param selectedPort
 	 */
 	public void connect(String selectedPort) {
-
 		try {
 			serialPort = portMap.get(selectedPort);
 
@@ -90,22 +66,12 @@ public class Communicator {
 			initIOStream();
 
 			// logging
-			logText = selectedPort + " opened successfully.";
-			System.out.println(logText);
-
-			// CODE ON SETTING BAUD RATE ETC OMITTED
-			// XBEE PAIR ASSUMED TO HAVE SAME SETTINGS ALREADY
-
-			// } catch (PortInUseException e) {
-			// logText = selectedPort + " is in use. (" + e.toString() + ")";
-			//
-			// System.out.println(logText);
+			System.out.println(selectedPort + " opened successfully.");
 		} catch (Exception e) {
 			logText = "Failed to open " + selectedPort + "(" + e.toString() + ")";
 			System.out.println(logText);
 			e.printStackTrace();
 		}
-
 	}
 
 	/**
@@ -126,12 +92,12 @@ public class Communicator {
 
 	private void knock() {
 		for (int i = 0; i < 8; i++) {
-			writeData(new byte[]{(byte) 0xc0});
+			ping();
 		}
 	}
 
 	private boolean ping() {
-		writeData(new byte[]{(byte) 0xc0});
+		writeData(new byte[] { (byte) 0xc0 });
 		return buffer[0] == 0x21;
 	}
 
@@ -139,13 +105,11 @@ public class Communicator {
 	 * This method disconnects the serial communication by first closing the
 	 * serialPort and then closing the IOStreams
 	 * 
-	 * 
 	 */
 	public void disconnect() {
 		if (!serialPort.isOpen())
 			return;
 		try {
-			// serialPort.removeEventListener();
 			input.close();
 			output.close();
 			serialPort.closePort();
@@ -165,7 +129,8 @@ public class Communicator {
 	 * 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 
+	 * 
+	 * @return
 	 * 
 	 * 
 	 */
@@ -245,7 +210,7 @@ public class Communicator {
 			return 0;
 		}
 	}
-	
+
 	/**
 	 * @return the portMap
 	 */

+ 127 - 0
src/eu/tankernn/grid/model/ComputerModel.java

@@ -0,0 +1,127 @@
+package eu.tankernn.grid.model;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This model contains two main data members as well as some data members used
+ * to configure the calculations and two checks
+ *
+ * Along with all the getters and setters this model has two methods used for
+ * polling and calculating.
+ *
+ * @author Roel
+ */
+public class ComputerModel {
+
+	// The main components of the Computermodel
+	private Sensor sensor;
+	private GRID grid;
+
+	/**
+	 * A global minimum percentage. This is used to prevent the controller from
+	 * constantly turning the fans on and off.
+	 */
+	private int minRPM = 30;
+
+	/**
+	 *
+	 * All members get initialised here.
+	 */
+	public ComputerModel() {
+		grid = new GRID();
+
+		try {
+			sensor = new Sensor();
+		} catch (Exception ex) {
+			Logger.getLogger(ComputerModel.class.getName()).log(Level.SEVERE, "Failed to init sensor.", ex);
+		}
+	}
+
+	/**
+	 *
+	 * Currently only the pollCPUPackageTemp method of the sensor object is
+	 * called This can change in the future
+	 *
+	 */
+	public void poll() {
+		System.out.println("Polling...");
+
+		grid.pollFans();
+
+		try {
+			getSensor().pollCPUTemp();
+			getSensor().pollCPUMax();
+			getSensor().pollGPUTemp();
+			getSensor().pollGPUMax();
+		} catch (Exception ex) {
+			System.out.println("Temperature polling failed");
+			ex.printStackTrace();
+		}
+	}
+
+	/**
+	 *
+	 * In this method the percentage to sent is computed. The calculation aims
+	 * to act as a proportional controller. A later step could be to add an
+	 * integral controller to the calculation to get a better calculated fan
+	 * curve
+	 *
+	 */
+	public void compute() {
+		grid.updateFanSpeeds(getTemp());
+	}
+
+	/**
+	 * A getter for the Sensor Object to make the methods of the object
+	 * available
+	 *
+	 * @return the sensor
+	 */
+	public Sensor getSensor() {
+		return sensor;
+	}
+
+	/**
+	 * A getter for the GRID Object to make the methods of the object available
+	 *
+	 * @return the grid
+	 */
+	public GRID getGrid() {
+		return grid;
+	}
+
+	/**
+	 * This setter overwrites the old GRID with a new Object with the
+	 * selectedport as the COM port to connect to
+	 *
+	 * @param selectedPort The com port the GRID controller is located at
+	 */
+	public void setGrid(String selectedPort) {
+		grid.getCommunicator().connect(selectedPort);
+	}
+
+	/**
+	 * @return the minRPM
+	 */
+	public double getMinRPM() {
+		return minRPM;
+	}
+
+	/**
+	 *
+	 * @param minRPM
+	 */
+	public void setMinRPM(int minRPM) {
+		this.minRPM = minRPM;
+	}
+	
+	/**
+	 * 
+	 * @return The temperature used to calculate fan speeds.
+	 */
+	public double getTemp() {
+		// TODO Calculate temp based on CPU/GPU
+		return 0;
+	}
+}

+ 68 - 0
src/eu/tankernn/grid/model/GRID.java

@@ -0,0 +1,68 @@
+package eu.tankernn.grid.model;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
+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 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
+ */
+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() {
+		fans = IntStream.range(0, 5).mapToObj(i -> new Fan(this, i)).toArray(Fan[]::new);
+
+		communicator = new Communicator();
+		communicator.searchForPorts();
+	}
+
+	/**
+	 * This method simply runs the disconnect method of the communicator.
+	 */
+	public void disconnect() {
+		getCommunicator().disconnect();
+	}
+
+	public Fan getFan(int index) {
+		return fans[index];
+	}
+
+	public Communicator getCommunicator() {
+		return communicator;
+	}
+
+	public double getTotalWattage() {
+		return Arrays.stream(fans).mapToDouble(Fan::getWattage).sum();
+	}
+
+	public void pollFans() {
+		fanStream().forEach(Fan::poll);
+	}
+
+	public void updateFanSpeeds(double temp) {
+		fanStream().forEach(f -> f.update(temp));
+	}
+
+	public Stream<Fan> fanStream() {
+		return Arrays.stream(fans);
+	}
+
+}

+ 5 - 6
src/camsucks/model/Sensor.java → src/eu/tankernn/grid/model/Sensor.java

@@ -1,4 +1,6 @@
-package camsucks.model;
+package eu.tankernn.grid.model;
+
+import java.io.IOException;
 
 /**
  *
@@ -23,11 +25,9 @@ public class Sensor {
      * The constructor for this class
      * At the start the lists of sensors are made with the help of the jWMI class
      * Then the number of cores of the system is calculated
-     * 
-     * @throws Exception when the WMI value can't be obtained
+     * @throws IOException when the WMI value can't be obtained
      */
-    public Sensor() throws Exception {
-        
+    public Sensor() throws IOException {
         temperatureSensorList = jWMI.getWMISensorList("Temperature").split(", ");
         loadSensorList = jWMI.getWMISensorList("Load").split(", ");
         //System.out.println(Arrays.toString(temperatureSensorList));
@@ -45,7 +45,6 @@ public class Sensor {
                 }
             }
         }
-
     }
 
     /**

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

@@ -1,4 +1,4 @@
-package camsucks.model;
+package eu.tankernn.grid.model;
 
 import java.io.BufferedReader;
 import java.io.File;