Index: hci/trunk/eneraptor-web-app/target/eneraptor-web-app-0.4.war
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: hci/trunk/eneraptor-web-app/web-app/css/style.css
===================================================================
--- hci/trunk/eneraptor-web-app/web-app/css/style.css	(revision 65)
+++ hci/trunk/eneraptor-web-app/web-app/css/style.css	(revision 66)
@@ -422,6 +422,7 @@
 .actions-add{background:transparent url(../img/icons/script_add.png) no-repeat left;}
 
 .config-main{background:transparent url(../img/icons/eye.png) no-repeat left;}
-.config-hci{background:transparent url(../img/icons/application.png) no-repeat left;}
-.config-logic{background:transparent url(../img/icons/cog.png) no-repeat left;}
-.config-connection{background:transparent url(../img/icons/connect.png) no-repeat left;}
\ No newline at end of file
+.config-hci{background:transparent url(../img/icons/calculator.png) no-repeat left;}
+.config-logic{background:transparent url(../img/icons/processor.png) no-repeat left;}
+.config-connection{background:transparent url(../img/icons/connect.png) no-repeat left;}
+.config-database{background:transparent url(../img/icons/database.png) no-repeat left;}
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/web-app/img/icons/processor.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: hci/trunk/eneraptor-web-app/web-app/img/icons/processor.png
===================================================================
--- hci/trunk/eneraptor-web-app/web-app/img/icons/processor.png	(revision 0)
+++ hci/trunk/eneraptor-web-app/web-app/img/icons/processor.png	(revision 66)

Property changes on: hci/trunk/eneraptor-web-app/web-app/img/icons/processor.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/MainMenuService.groovy	(revision 66)
@@ -55,9 +55,10 @@
 		
 		configSubMenu = new ArrayList()
 		configSubMenu.add(new MenuItem("Overview","config","main"))
-		configSubMenu.add(new MenuItem("Configure HCI","config","hci"))
-		configSubMenu.add(new MenuItem("Configure the Logic","config","logic"))
-		configSubMenu.add(new MenuItem("Configure HCI to Logic connection","config","connection"))
+		configSubMenu.add(new MenuItem("Configure devices","config","hci"))
+		configSubMenu.add(new MenuItem("Configure hardware set (card)","config","logic"))
+		configSubMenu.add(new MenuItem("Configure connection","config","connection"))
+		configSubMenu.add(new MenuItem("Configure database","config","database"))
 		
 	}
 	
Index: hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/services/com/eneraptor/hci/HciLogicCommService.groovy	(revision 66)
@@ -4,7 +4,7 @@
 
     static transactional = true
 
-    Map getReplyToRequest(String requestContent) {
+    Map getReplyToRequest(String requestContent,String ipAddress,int portNum) {
 		
 		Map reply = new HashMap()
 		
@@ -11,12 +11,9 @@
 		Socket logicSocket = null;
 		PrintWriter toLogic = null;
 		BufferedReader fromLogic = null;
-		
-		def ipAddress = InternalConfig.findByConfigId("logic-ip")['configVal']
-		def portNum = InternalConfig.findByConfigId("logic-port")['configVal']
 
 		try {
-			logicSocket = new Socket(ipAddress, portNum as int);
+			logicSocket = new Socket(ipAddress, portNum);
 			toLogic = new PrintWriter(logicSocket.getOutputStream(), true);
 			fromLogic = new BufferedReader(new InputStreamReader(
 										logicSocket.getInputStream()));
Index: hci/trunk/eneraptor-web-app/grails-app/conf/com/eneraptor/hci/LoginFilters.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/conf/com/eneraptor/hci/LoginFilters.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/conf/com/eneraptor/hci/LoginFilters.groovy	(revision 66)
@@ -7,8 +7,17 @@
             before = {
                 
 				if(!session["loggedIn"]) {
+					
 					redirect(controller: 'login');
+					return false
+					
+				} else if (!session["hwSet"] && params.controller != 'chooseHwSet') {
+				
+					redirect(controller: 'chooseHwSet', action: 'main')
+					return false
+					
 				}
+				
 				return true;
 				
             }
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/StatisticsController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/StatisticsController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/StatisticsController.groovy	(revision 66)
@@ -16,7 +16,8 @@
 		List savedGraphs = new ArrayList()
 		List combinedGraphs = new ArrayList()
 		
-		savedGraphs = EneGraph.list()
+		savedGraphs = EneGraph.findAllByHwSet(session.hwSet)
+		
 		combinedGraphs = CombGraph.list()
 			
 		[savedGraphs: savedGraphs, combinedGraphs:combinedGraphs]
@@ -31,7 +32,7 @@
 		List devices = new ArrayList()
 		List devicesFriendly = new ArrayList()
 		
-		DeviceInfo.list().each {
+		DeviceInfo.findAllByHwSet(session.hwSet).each {
 			devices << it.deviceId
 			devicesFriendly << it.friendlyName
 		}
@@ -78,6 +79,8 @@
 			deviceId: params['deviceId']
 		)
 		
+		HardwareSet.get(session.hwSet.id).addToGraphs(newEneGraph)
+		
 		if(!newEneGraph.validate()) {
 			errors += "<p>Graph could not be created - there were some input errors. Please check if all input values are valid.</p>"
 			flash['errors'] = errors
@@ -118,7 +121,7 @@
 		List devices = new ArrayList()
 		List devicesFriendly = new ArrayList()
 		
-		DeviceInfo.list().each {
+		DeviceInfo.findAllByHwSet(session.hwSet).each {
 			devices << it.deviceId
 			devicesFriendly << it.friendlyName
 		}
@@ -167,7 +170,7 @@
 	
 	def newReport = {
 		
-		def graphsAll = EneGraph.list()
+		def graphsAll = EneGraph.findAllByHwSet(session.hwSet)
 		def graphs = new ArrayList()
 		def graphsKeys = new ArrayList()
 		graphsAll.each {
@@ -420,16 +423,20 @@
 			def graphToDelete = EneGraph.get(params['id'])
 			if(graphToDelete) {
 				
-				if(graphToDelete.delete()) {
-					flash['confirms'] = "<p>Graph deleted successfully.</p>"
-					redirect(action:'graphs')
-					return true
-				} else {
+				def idOfDeleted = graphToDelete.id
+				
+				try {
+					graphToDelete.delete(flush:true)
+				} catch (Exception e) {
 					flash['errors'] = "<p>Cannot remove this graph. This graph is part of a <b>combined</b> graph.</p><p>You should remove the <b>combined</b> graph first.</p>"
 					redirect(action:'graphs')
 					return false
 				}
 				
+				flash['confirms'] = "<p>Graph deleted successfully.</p>"
+				redirect(action:'graphs')
+				return true
+				
 			} else {
 				flash['errors'] = "<p>No graph was deleted. Graph ID invalid!</p>"
 				redirect(action:'graphs')
@@ -448,9 +455,10 @@
 	
 	def newCombGraph = {
 		
-		def graphs = EneGraph.list()
+		def graphs = EneGraph.findAllByHwSet(session.hwSet)
+		def otherGraphs = EneGraph.findAllByHwSetNotEqual(session.hwSet)
 		
-		[graphs:graphs]
+		[graphs:graphs, otherGraphs: otherGraphs]
 		
 	}
 	
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ChooseHwSetController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ChooseHwSetController.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ChooseHwSetController.groovy	(revision 66)
@@ -0,0 +1,86 @@
+package com.eneraptor.hci
+
+class ChooseHwSetController {
+
+    def index = { }
+	
+	def main = {
+		
+		def hwSets = HardwareSet.list()
+		
+		[hwSets: hwSets]
+		
+	}
+	
+	def mainDo = {
+		
+		HardwareSet chosenHwSet = HardwareSet.get(params['hwSet'])
+		
+		if(chosenHwSet) {
+			
+			session['hwSet'] = chosenHwSet
+			redirect(controller:'sysState',action:'main')
+			return true
+			
+		}
+		
+		redirect(action:'main')
+		return false
+		
+	}
+	
+	def addNew = { }
+	
+	def addNewDo = {
+		
+		HardwareSet newHwSet = new HardwareSet(params)
+		
+		if(!newHwSet.validate()) {
+			redirect(action:'addNew',params:(params << ['invalid':true]))
+			return false
+		} else {
+			newHwSet.save()
+			redirect(action:main)
+			return true
+		}
+		
+	}
+	
+	def change = {
+		
+		def chosenHwSet = HardwareSet.get(params.id)
+		
+		if(chosenHwSet) {
+			session['hwSet'] = chosenHwSet
+			flash.confirms = "<p>Changed current hardware set to " + chosenHwSet.name + "</p>"
+			redirect(controller:'sysState',action:'main')
+			return true
+		} else {
+			flash.errors = "<p>Could not change current hardware set (card). The ID specified is not valid!</p>"
+			redirect(controller:'sysState',action:'main')
+		}
+		
+		return false
+		
+	}
+	
+	def delete = {
+		
+		def hwSet = HardwareSet.get(params['id'])
+		
+		if(hwSet) {
+			
+			session.hwSet = null
+			hwSet.delete()
+			redirect(action:'main')
+			return true
+			
+		} else {
+			flash.errors = '<p>Could not delete hardware set (card). The ID specified is invalid.</p>'
+			redirect(controller:'config',action:'logic')
+			return false
+		}
+		
+	}
+	
+}
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysStateController.groovy	(revision 66)
@@ -7,7 +7,15 @@
 	
     def main = {
 		
-		List inDevices = DeviceInfo.findAllByInputDevice(true, [sort:'friendlyName', order:'asc'])
+		def crit1 = DeviceInfo.createCriteria()
+		List inDevices = crit1 {
+			and {
+				eq("inputDevice",true)
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
+		}
+		
 		List inDevicesData = new ArrayList()
 		inDevices.each {
 			Map inDeviceDataEntry = new HashMap()
@@ -17,7 +25,15 @@
 			inDevicesData << inDeviceDataEntry
 		}
 		
-		List outDevices = DeviceInfo.findAllByOutputDevice(true, [sort:'friendlyName', order:'asc'])
+		def crit2 = DeviceInfo.createCriteria()
+		List outDevices = crit2 {
+			and {
+				eq("outputDevice",true)
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
+		}
+
 		List outDevicesData = new ArrayList()
 		outDevices.each {
 			Map outDeviceDataEntry = new HashMap()
@@ -33,7 +49,15 @@
 	
 	def measure = {
 		
-		List inDevices = DeviceInfo.findAllByInputDevice(true, [sort:'friendlyName', order:'asc'])
+		def crit1 = DeviceInfo.createCriteria()
+		List inDevices = crit1 {
+			and {
+				eq("inputDevice",true)
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
+		}
+		
 		List inDevicesData = new ArrayList()
 		inDevices.each {
 			Map inDeviceDataEntry = new HashMap()
@@ -92,7 +116,15 @@
 	
 	def actions = {
 		
-		List outDevices = DeviceInfo.findAllByOutputDevice(true, [sort:'friendlyName', order:'asc'])
+		def crit2 = DeviceInfo.createCriteria()
+		List outDevices = crit2 {
+			and {
+				eq("outputDevice",true)
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
+		}
+		
 		List outDevicesData = new ArrayList()
 		outDevices.each {
 			Map outDeviceDataEntry = new HashMap()
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ActionsController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ActionsController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ActionsController.groovy	(revision 66)
@@ -17,7 +17,7 @@
 	def getActions = {
 		
 		String reqStr = "<?xml version=\"1.0\"?><hci-request type=\"getScenarios\"></hci-request>"
-		Map reply = hciLogicCommService.getReplyToRequest(reqStr)
+		Map reply = hciLogicCommService.getReplyToRequest(reqStr,session.hwSet.IPaddress,session.hwSet.portNumber)
 		
 		if(reply['status'] == 'error' || reply['content'] == null) {
 			return [replyError: reply['content']]
@@ -43,7 +43,7 @@
 	def viewAction = {
 		
 		String reqStr = "<?xml version=\"1.0\"?><hci-request type=\"getScenarios\"></hci-request>"
-		Map reply = hciLogicCommService.getReplyToRequest(reqStr)
+		Map reply = hciLogicCommService.getReplyToRequest(reqStr,session.hwSet.IPaddress,session.hwSet.portNumber)
 		
 		if(reply['status'] == 'error' || reply['content'] == null) {
 			flash['errors'] = "<p>Error connecting with logic: " + reply['content'] + "</p>"
@@ -94,7 +94,7 @@
 		// First part: get XML from logic and modify
 		
 		String reqStr = "<?xml version=\"1.0\"?><hci-request type=\"getScenarios\"></hci-request>"
-		Map reply = hciLogicCommService.getReplyToRequest(reqStr)
+		Map reply = hciLogicCommService.getReplyToRequest(reqStr,session.hwSet.IPaddress,session.hwSet.portNumber)
 		
 		if(reply['status'] == 'error' || reply['content'] == null) {
 			flash['errors'] = "<p>Error connecting with logic: " + reply['content'] + "</p>"
@@ -118,7 +118,7 @@
 				
 				// Second part: give modified XML to logic
 				
-				Map reply2 = hciLogicCommService.getReplyToRequest(result)
+				Map reply2 = hciLogicCommService.getReplyToRequest(result,session.hwSet.IPaddress,session.hwSet.portNumber)
 				
 				if(reply2['status'] == 'error' || reply2['content'] == null) {
 					flash['errors'] = "<p>Error connecting with logic: " + reply2['content'] + "</p>"
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/SysLogController.groovy	(revision 66)
@@ -41,8 +41,17 @@
 		flash['warnings'] = null
 		
 		List devicesForCheckBox = new ArrayList()
-		DeviceInfo.findAllByInputDeviceOrOutputDevice(true,true).each {
-			devicesForCheckBox << it
+		
+		def crit1 = DeviceInfo.createCriteria()
+		devicesForCheckBox = crit1 {
+			and {
+				or {
+					eq("outputDevice",true)
+					eq("inputDevice",true)
+				}
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
 		}
 		
 		def entries = new ArrayList()
@@ -132,8 +141,13 @@
 		List devices = new ArrayList()
 		List data = new ArrayList()
 		
-		DeviceInfo.findAllByInputDevice(true).each {
-			devices << it
+		def crit1 = DeviceInfo.createCriteria()
+		devices = crit1 {
+			and {
+				eq("inputDevice",true)
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
 		}
 		
 		if(params['dataList'])
@@ -162,8 +176,17 @@
 	def export = {
 		
 		List devicesForCheckBox = new ArrayList()
-		DeviceInfo.findAllByInputDeviceOrOutputDevice(true,true).each {
-			devicesForCheckBox << it
+		
+		def crit1 = DeviceInfo.createCriteria()
+		devicesForCheckBox = crit1 {
+			and {
+				or {
+					eq("outputDevice",true)
+					eq("inputDevice",true)
+				}
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
 		}
 		
 		[devicesForCheckBox: devicesForCheckBox]
@@ -241,8 +264,17 @@
 	def clear = {
 		
 		List devicesForCheckBox = new ArrayList()
-		DeviceInfo.findAllByInputDeviceOrOutputDevice(true,true).each {
-			devicesForCheckBox << it
+		
+		def crit1 = DeviceInfo.createCriteria()
+		devicesForCheckBox = crit1 {
+			and {
+				or {
+					eq("outputDevice",true)
+					eq("inputDevice",true)
+				}
+				eq("hwSet",session.hwSet)
+			}
+			order("friendlyName","asc")
 		}
 		
 		[devicesForCheckBox: devicesForCheckBox]
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/ConfigController.groovy	(revision 66)
@@ -33,7 +33,8 @@
 		
 		*/
 		
-		def allDevices = DeviceInfo.list()
+		def allDevices = HardwareSet.get(session.hwSet.id).devices
+		
 		[conf: InternalConfig, devices: allDevices, totalSpace: totalSpace, freeSpace: freeSpace, percent: percent]		
 	}
 	
@@ -42,6 +43,7 @@
 	
 	def addDeviceSave = {
 		def newDevice = new DeviceInfo(params)
+		HardwareSet.get(session.hwSet.id).addToDevices(newDevice)
 		if(newDevice.validate() && (params.inputDevice || params.outputDevice)) {
 			newDevice.save()
 			flash['confirms'] = "<p>New device added successfully.</p>"
@@ -107,14 +109,18 @@
 	
 	def logic = {
 		
-		[conf: InternalConfig]
+		def hwSet = session.hwSet
 		
+		[hwSet:hwSet]
+		
 	}
 	
 	def connection = {
 		
-		[conf: InternalConfig]
+		def hwSet = session.hwSet
 		
+		[hwSet: hwSet]
+		
 	}
 	
 	def saveConnection = {
@@ -121,13 +127,14 @@
 		
 		if(params['logic-ip'] == 'localhost') params['logic-ip'] = '127.0.0.1'
 		
-		if(params['logic-ip'] && params['logic-port']) {
-			InternalConfig.findByConfigId('logic-ip').configVal = params['logic-ip']
-			InternalConfig.findByConfigId('logic-port').configVal = params['logic-port']
+		if(params['logic-ip'] && params['logic-port'] && params['logic-port'].isInteger()) {
+			
+			session.hwSet.IPaddress = params['logic-ip']
+			session.hwSet.portNumber = (params['logic-port'] as int)
 			flash['confirms'] = "<p>Changes saved.</p>"
 			redirect(action: 'connection')
 		} else {
-			flash['errors'] = "<p>Logic IP address and port fields cannot be blank.</p>"
+			flash['errors'] = "<p>Could not save changes.</p><p>Logic IP address and port fields cannot be blank. Port number must be an integer.</p>"
 			redirect(action: 'connection')
 		}
 		
@@ -171,5 +178,7 @@
 	def getHelp = {
 		[what : params.what]
 	}
+	
+	def database = { }
 	
 }
Index: hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/controllers/com/eneraptor/hci/LogicRequestController.groovy	(revision 66)
@@ -11,13 +11,13 @@
 		
 		def output = "";
 		output += reportService.println("Conection test using")
-		output += reportService.println("Logic IP address: " + InternalConfig.findByConfigId('logic-ip').configVal)
-		output += reportService.println("Logic port number: " + InternalConfig.findByConfigId('logic-port').configVal)
+		output += reportService.println("Logic IP address: " + session.hwSet.IPaddress)
+		output += reportService.println("Logic port number: " + session.hwSet.portNumber)
 		
 		output += reportService.println("Test started")
 		
 		String reqStr = "<?xml version=\"1.0\"?><hci-request type=\"checkConnection\"><data>12345</data></hci-request>"
-		Map testReply = hciLogicCommService.getReplyToRequest(reqStr)
+		Map testReply = hciLogicCommService.getReplyToRequest(reqStr,session.hwSet.IPaddress,session.hwSet.portNumber)
 		
 		if(testReply['status'] == "error") {
 			output += reportService.println("<span style='color:red;'>Error: " + testReply['content'] + "</span>")
Index: hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/EneGraph.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/EneGraph.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/EneGraph.groovy	(revision 66)
@@ -15,10 +15,12 @@
 	int advMonthTimeFrameStart
 	int advMonthTimeFrameEnd
 	String deviceId
+	
+	static belongsTo = [hwSet: HardwareSet]
 	
     static constraints = {
 		
-		name(blank:false, unique:true)
+		name(blank:false, unique:'hwSet')
 		type(blank:false, inList:["max","min","avg","sum"])
 		timeFrameType(blank:false, inList:["day","month","year","custom"])
 		timeFrameStart(blank:false)
Index: hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/HardwareSet.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/HardwareSet.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/HardwareSet.groovy	(revision 66)
@@ -0,0 +1,19 @@
+package com.eneraptor.hci
+
+class HardwareSet {
+	
+	String hardId
+	String name
+	String IPaddress
+	int portNumber
+	
+	static hasMany = [
+		graphs: EneGraph,
+		devices: DeviceInfo
+	]
+	
+    static constraints = {
+		hardId(blank:false,unique:true)
+		name(blank:false,unique:true)
+    }
+}
Index: hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/domain/com/eneraptor/hci/DeviceInfo.groovy	(revision 66)
@@ -9,10 +9,10 @@
 	boolean inputDevice
 	boolean outputDevice
 	
-	 
+	static belongsTo = [hwSet: HardwareSet]
 	
     static constraints = {
-		deviceId(blank: false, unique: true)
+		deviceId(blank: false, unique: 'hwSet')
 		friendlyName(blank: false, maxSize: 64)
 		description(nullable: true, maxSize: 128)
 		iconPath(nullable: true)
Index: hci/trunk/eneraptor-web-app/grails-app/views/statistics/newCombGraph.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/statistics/newCombGraph.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/statistics/newCombGraph.gsp	(revision 66)
@@ -24,9 +24,14 @@
 				<p>Select by clicking on the grpah's name while holding CTRL key on your keyboard.</p>
 				<br />
 				<select multiple="multiple" name="graphsToCombine" id="graphsToCombine" size="10" style="width:820px;">
-					<g:each in="${graphs}" var="graph">
-						<option value="${graph.id}">(${graph.type}) ${graph.name}</option>
-					</g:each>
+					<optgroup label="Current hardware set's (card's) graphs"></optgroup>
+						<g:each in="${graphs}" var="graph">
+							<option value="${graph.id}">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(${graph.type}) ${graph.name}</option>
+						</g:each>
+					<optgroup label="Other hardware set's (card's) graphs"></optgroup>
+						<g:each in="${otherGraphs}" var="ograph">
+							<option value="${ograph.id}">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(${ograph.type}) ${ograph.name}</option>
+						</g:each>
 				</select>
 				<br /><br />
 			</fieldset>
Index: hci/trunk/eneraptor-web-app/grails-app/views/statistics/showCombGraph.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/statistics/showCombGraph.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/statistics/showCombGraph.gsp	(revision 66)
@@ -14,12 +14,18 @@
 			var options = {
 				lines: { show: true },
 				points: { show: true },
-				xaxis: { mode: "time", timeformat: "%y/%m/%d %H:%M" }
+				xaxis: { mode: "time", timeformat: "%y/%m/%d %H:%M" },
+				legend: {
+				    container: $('legendContainer')
+				}
 			};
 		</g:javascript>
 		<div class="chart">
 			<flot:plot id="placeholder" style="width: 900px; height: 300px; padding:5px;" data="data" options="options" />
 		</div>
+		<br />
+		<p>Legend:</p>
+		<div id="legendContainer" name="legendContainer"></div>
 	</erptr:box>
 
 </body>
Index: hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/main.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/main.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/main.gsp	(revision 66)
@@ -0,0 +1,38 @@
+<html>
+
+<head>
+	<title>Eneraptor &raquo; Hardware set (card) selection</title>
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'theme.css')}" />
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'style.css')}" />
+	<!--[if IE]>
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'ie-sucks.css')}" />
+	<![endif]-->
+</head>
+
+<body>
+	<center>
+		<br />
+		<img src="${g.resource(dir:'img', file:'logo.jpg')}" />
+		<div style="width:518px;background:white;padding:10px;margin-top:20px;">
+			<erptr:box title="Hardware set selection">
+				
+				<p>Before you continue using Eneraptor, please choose hardware set (card) to control:</p>
+
+				<g:form action="mainDo">
+				
+					<g:select name="hwSet" from="${hwSets}" optionKey="id" optionValue="name" style="width:350px;" />
+					&nbsp;
+					<g:submitButton name="mainSubmit" value="Select" />
+					<br /><br />
+					<g:link action="addNew" style="float:right;"><erptr:icon w="add" />&nbsp;Add new...</g:link>
+					
+					<br />
+					
+				</g:form>
+				
+			</erptr:box>
+		</div>
+	</center>
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/addNew.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/addNew.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/chooseHwSet/addNew.gsp	(revision 66)
@@ -0,0 +1,56 @@
+<html>
+
+<head>
+	<title>Eneraptor &raquo; Adding new hardware set (card)</title>
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'theme.css')}" />
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'style.css')}" />
+	<!--[if IE]>
+	<link rel="stylesheet" type="text/css" href="${g.resource(dir:'css/', file:'ie-sucks.css')}" />
+	<![endif]-->
+</head>
+
+<body>
+	<center>
+		<br />
+		<img src="${g.resource(dir:'img', file:'logo.jpg')}" />
+		<div style="width:518px;background:white;padding:10px;margin-top:20px;">
+		
+			<g:if test="${params.invalid}">
+				<div style="width:100%;border:1px solid #E33939;'">
+					<p style="color:#E33939;"><erptr:icon w="exclamation" />Sorry, some fields were either left blank or invalid.</p>
+				</div>
+				<br />
+			</g:if>
+
+			<erptr:box title="New hardware set (card)">
+				
+				<p>Please enter information about the new hardware set (card). All fiealds are required.</p>
+
+				<g:form action="addNewDo">
+				
+					<label for="hardId">Card's unique ID:</label>
+					<g:textField name="hardId" value="${params.hardId?:''}" />
+					<br /><br />
+					
+					<label for="name">Card's unique name:</label>
+					<g:textField name="name" value="${params.name?:''}" />
+					<br /><br />
+					
+					<label for="IPaddress">Card's IP address:</label>
+					<g:textField name="IPaddress" value="${params.IPaddress?:'127.0.0.1'}" />
+					<br /><br />
+					
+					<label for="portNumber">Logic's port number:</label>
+					<g:textField name="portNumber" value="${params.portNumber?:'1100'}" />
+					<br /><br />
+					
+					<g:submitButton name="addNewSubmit" value="Sumbit" />
+					
+				</g:form>
+				
+			</erptr:box>
+		</div>
+	</center>
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/layouts/main.gsp	(revision 66)
@@ -18,42 +18,19 @@
 		
 		<!-- Energy saved -->
 		<div style="position:absolute;top:10px;">
-			<div style="position:absolute;left:250px;color:white;">
-				<center style="width:150px;">
-					<p style="font-size:75%;">From start</p>
-					<p><b>1243432.45</b> kWh</p>
-					<p style="font-size:75%;">of energy saved</p>
-				</center>
+			<div style="position:relative;left:650px;top:15px;">
+				<select style="width:310px;" onchange="location.href=escape(this.options[this.selectedIndex].value)">
+					<g:each in="${com.eneraptor.hci.HardwareSet.list()}" var="hwSet">
+						<g:if test="${hwSet.id == session.hwSet.id}">
+							<option value="${createLink(controller:'chooseHwSet',action:'change',id:hwSet.id)}" selected="selected">${hwSet.name}</option>
+						</g:if>
+						<g:else>
+							<option value="${createLink(controller:'chooseHwSet',action:'change',id:hwSet.id)}">${hwSet.name}</option>
+						</g:else>
+					</g:each>
+				</select>
 			</div>
-			<div style="position:absolute;left:400px;color:white;">
-				<center style="width:150px;">
-					<p style="font-size:75%;">Last year</p>
-					<p><b>87329.84</b> kWh</p>
-					<p style="font-size:75%;">of energy saved</p>
-				</center>
-			</div>
-			<div style="position:absolute;left:550px;color:white;">
-				<center style="width:150px;">
-					<p style="font-size:75%;">Last month</p>
-					<p><b>5644.56</b> kWh</p>
-					<p style="font-size:75%;">of energy saved</p>
-				</center>
-			</div>
-			<div style="position:absolute;left:700px;color:white;">
-				<center style="width:150px;">
-					<p style="font-size:75%;">Last week</p>
-					<p><b>453.00</b> kWh</p>
-					<p style="font-size:75%;">of energy saved</p>
-				</center>
-			</div>
-			<div style="position:absolute;left:850px;color:white;">
-				<center style="width:150px;">
-					<p style="font-size:75%;">Last day</p>
-					<p><b>23.28</b> kWh</p>
-					<p style="font-size:75%;">of energy saved</p>
-				</center>
 		</div>
-		</div>
 		<!-- / Energy saved -->
 		
 		<div id="header">
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/logic.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/logic.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/logic.gsp	(revision 66)
@@ -1,20 +1,39 @@
 <html>
 
 <head>
-	<title>Configuration &raquo; Logic</title>
+	<title>Configuration &raquo; Hardware set (card)</title>
 	<meta name="layout" content="main" />
 </head>
 
 <body>
 	
-	<erptr:box title="Logic configuration">
-		<g:form name="logic-config-form" action="saveLogic">
-		
-			<p>TODO: Logic configuration</p>
-			
-		</g:form>
+	<erptr:box title="Hardware set (card) information">
+	
+		<p>Hardware set's (card's) unique ID: <b>${hwSet.hardId}</b></p>
+		<p>Hardware set's (card's) name: <b>${hwSet.name}</b></p>
+
 	</erptr:box>
 	
+	<erptr:box title="Configuration">
+	
+		<p>If you no longer have or need currently selected hardware set (card), you may delete it.</p>
+		<p style="color:red;"><i>Warning: deleting current hardware set (card) <b>will also delete</b> all of it's devices, graphs, and other saved data, but <b>will not delete</b> any logged data in the database.</i></p>
+		<br />
+		<p><a href="javascript:confirmDelete();"><erptr:icon w="delete" />&nbsp;Delete current hardware set (card)</a></p>
+	
+	</erptr:box>
+	
+	<g:javascript>
+	function confirmDelete() {
+		
+		var answer = confirm("Do you really want to proceed?\nAll of current hardware set's (card's) data will be deleted.");
+		if(answer) {
+			window.location = "<g:createLink controller="chooseHwSet" action="delete" id="${hwSet.id}" />";
+		}
+		
+	}
+	</g:javascript>
+	
 </body>
 
 </html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/connection.gsp	(revision 66)
@@ -16,13 +16,13 @@
 				<legend>Basic</legend>
 		
 				<label for="logic-ip">Logic's IP address</label>
-				<g:textField name="logic-ip" value="${conf.findByConfigId('logic-ip').configVal}" />
+				<g:textField name="logic-ip" value="${hwSet.IPaddress}" />
 				<erptr:helpLink for="logic-ip" />
 				
 				<br />
 				
 				<label for="logic-port">Logic's port number</label>
-				<g:textField name="logic-port" value="${conf.findByConfigId('logic-port').configVal}" />
+				<g:textField name="logic-port" value="${hwSet.portNumber}" />
 			
 				<br />
 			
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp	(revision 65)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/hci.gsp	(revision 66)
@@ -7,27 +7,6 @@
 
 <body>
 	
-	<erptr:box title="Information">
-		
-		<p>HCI Version: &nbsp;&nbsp;&nbsp;<span style="font-family:monospace;">${conf.findByConfigId('hci-version').configVal}</span></p>
-		
-		<!-- DISK USAGE - ONLY IF ENERAPTOR HCI IS SUPERUSER	
-		<p style="float: left;">Disk usage: &nbsp;&nbsp;&nbsp;</p>
-		<div style="float:left;">
-			<div style="width: 100px;border:1px solid grey;">
-				<div style="width:${percent}px;background:grey;">
-					&nbsp;
-				</div>
-			</div>
-		</div>
-		<span> &nbsp;&nbsp;&nbsp; ${percent}% (free space ${(int)freeSpace} MB) </span>
-		<g:if test="${percent >= 95}">
-				<i style="color:red;">&nbsp;&nbsp;&nbsp;Warning: disk is almost full. You should erase some old log entries.</i>
-		</g:if>
-		-->
-		
-	</erptr:box>
-	
 	<erptr:box title="Known devices">
 	
 		<table width="100%">
@@ -79,22 +58,6 @@
 	
 	</erptr:box>
 	
-	<erptr:box title="Database information">
-	
-		<p>Eneraptor system uses PostgreSQL database management system to store log data and HCI configuration.</p>
-		
-		<br />
-		
-		<div id="dbConfigHolder">
-			<g:remoteLink action="dbInfo" update="dbConfigHolder"><erptr:icon w="eye" />View database configuration</g:remoteLink>
-		</div>
-		
-		<br />
-		
-		<g:link action="dbExec"><erptr:icon w="database_edit" />Execute SQL queries manually</g:link>
-		
-	</erptr:box>
-	
 </body>
 
 </html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/grails-app/views/config/database.gsp
===================================================================
--- hci/trunk/eneraptor-web-app/grails-app/views/config/database.gsp	(revision 0)
+++ hci/trunk/eneraptor-web-app/grails-app/views/config/database.gsp	(revision 66)
@@ -0,0 +1,43 @@
+<html>
+
+<head>
+	<title>Configuration &raquo; Database</title>
+	<meta name="layout" content="main" />
+</head>
+
+<body>
+
+		<!-- DISK USAGE - ONLY IF ENERAPTOR HCI IS SUPERUSER	
+			<p style="float: left;">Disk usage: &nbsp;&nbsp;&nbsp;</p>
+			<div style="float:left;">
+				<div style="width: 100px;border:1px solid grey;">
+					<div style="width:${percent}px;background:grey;">
+						&nbsp;
+					</div>
+				</div>
+			</div>
+			<span> &nbsp;&nbsp;&nbsp; ${percent}% (free space ${(int)freeSpace} MB) </span>
+			<g:if test="${percent >= 95}">
+					<i style="color:red;">&nbsp;&nbsp;&nbsp;Warning: disk is almost full. You should erase some old log entries.</i>
+			</g:if>
+		-->
+	
+	<erptr:box title="Database information">
+	
+		<p>Eneraptor system uses PostgreSQL database management system to store log data and HCI configuration.</p>
+		
+		<br />
+		
+		<div id="dbConfigHolder">
+			<g:remoteLink action="dbInfo" update="dbConfigHolder"><erptr:icon w="eye" />View database configuration</g:remoteLink>
+		</div>
+		
+		<br />
+		
+		<g:link action="dbExec"><erptr:icon w="database_edit" />Execute SQL queries manually</g:link>
+		
+	</erptr:box>
+	
+</body>
+
+</html>
\ No newline at end of file
Index: hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ChooseHwSetControllerTests.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ChooseHwSetControllerTests.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/ChooseHwSetControllerTests.groovy	(revision 66)
@@ -0,0 +1,17 @@
+package com.eneraptor.hci
+
+import grails.test.*
+
+class ChooseHwSetControllerTests extends ControllerUnitTestCase {
+    protected void setUp() {
+        super.setUp()
+    }
+
+    protected void tearDown() {
+        super.tearDown()
+    }
+
+    void testSomething() {
+
+    }
+}
Index: hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HardwareSetTests.groovy
===================================================================
--- hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HardwareSetTests.groovy	(revision 0)
+++ hci/trunk/eneraptor-web-app/test/unit/com/eneraptor/hci/HardwareSetTests.groovy	(revision 66)
@@ -0,0 +1,17 @@
+package com.eneraptor.hci
+
+import grails.test.*
+
+class HardwareSetTests extends GrailsUnitTestCase {
+    protected void setUp() {
+        super.setUp()
+    }
+
+    protected void tearDown() {
+        super.tearDown()
+    }
+
+    void testSomething() {
+
+    }
+}
