Browse Source

Merge branch 'GlobalScheduler'

Andreas T. Meyer-Berg 4 years ago
parent
commit
69b7c0e71d
62 changed files with 4069 additions and 132 deletions
  1. 3 0
      .gitignore
  2. 1 0
      README.md
  3. 51 47
      build.gradle
  4. 16 0
      examples/CountingMetric.java
  5. 307 0
      examples/UnsupervisedAnomalyDetectionExample.java
  6. 343 0
      examples/UnsupervisedAnomalyDetectionExample2.java
  7. 426 0
      examples/classifier/BasicPacketClassifier.java
  8. 87 0
      examples/classifier/EMClustering.java
  9. 70 0
      examples/classifier/HierarchicalClustering.java
  10. 121 0
      examples/classifier/KMeansClustering.java
  11. 1 1
      gradle/wrapper/gradle-wrapper.properties
  12. BIN
      libs/weka.jar
  13. BIN
      libs_src/weka_src.jar
  14. 196 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ExampleAnomalyController.java
  15. 61 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java
  16. 22 2
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/NetworkController.java
  17. 43 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/PacketCaptureController.java
  18. 20 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Connection.java
  19. 22 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPerformance.java
  20. 3 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPrecision.java
  21. 31 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Link.java
  22. 29 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Packet.java
  23. 2 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollectionManager.java
  24. 46 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollector.java
  25. 16 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketSniffer.java
  26. 93 18
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Port.java
  27. 44 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PrecisionLink.java
  28. 39 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ProbabilityDistributionHandler.java
  29. 60 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SimulationManager.java
  30. 21 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SmartDevice.java
  31. 39 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/ImportConfiguration.java
  32. 25 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/devices/FloatSensorDevice.java
  33. 113 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/ConstantValueDistributionHandler.java
  34. 167 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/NormalDistributionHandler.java
  35. 168 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/PoissonDistributionHandler.java
  36. 6 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/distributionHandler/package-info.java
  37. 73 11
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java
  38. 6 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTT_packet.java
  39. 81 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/MQTTpublishPacket.java
  40. 6 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/packets/Ping_packet.java
  41. 31 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/AbstractEvent.java
  42. 21 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Schedulable.java
  43. 23 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/ScheduleComparator.java
  44. 125 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/Scheduler.java
  45. 6 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/scheduler/package-info.java
  46. 15 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/CountingMetric.java
  47. 1 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/Manipulation_RandomMove.java
  48. 20 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleConnection.java
  49. 21 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimpleLink.java
  50. 34 4
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacket.java
  51. 17 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/simpleImplementation/SimplePacketSniffer.java
  52. 11 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/MenuBar.java
  53. 152 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarInsertAnomalies.java
  54. 377 18
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/MenuBarNetworkExamples.java
  55. 7 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/menuBar/package-info.java
  56. 52 6
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/ConnectionCreationPanel.java
  57. 56 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/EditPacketSniffer.java
  58. 195 0
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortDistributionConfigurationPopUp.java
  59. 44 11
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/PortEditorPanel.java
  60. 1 1
      src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/view/popups/SmartDeviceCreationPopUp.java
  61. 1 1
      src/test/java/de/tu_darmstadt/tk/shNetSimTests/control/ConfigurationTest.java
  62. 1 1
      src/test/resources/control/testCompilation/project1/MQTT_protocolProject1.javaTest

+ 3 - 0
.gitignore

@@ -105,6 +105,9 @@ gradle-app.setting
 
 # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
 !gradle-wrapper.jar
+# Avoid if
+!/libs/*.jar
+!/libs_src/*.jar
 
 # Cache of project
 .gradletasknamecache

+ 1 - 0
README.md

@@ -27,6 +27,7 @@ Gradle downloads these during the build process
 
 * [JUnit4](https://junit.org/junit4/) - Java unit test framework
 * [Pcap4j](https://www.pcap4j.org/) - Java Library used for Pcap File creation (not yet implemented)
+* [Math3](https://commons.apache.org/proper/commons-math/) - Apache Common Maths (for Distribution function)
 
 <!-- PCAP file writing example (as part of the export manager - but probably required packet transformation): https://www.devdungeon.com/content/packet-capturing-java-pcap4j#writing_pcap_file -->
 

+ 51 - 47
build.gradle

@@ -1,47 +1,51 @@
-/*
- * This file was generated by the Gradle 'init' task.
- *
- * This is a general purpose Gradle build.
- * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/
- */
-
-apply plugin: 'java'
-apply plugin: 'eclipse'
-apply plugin: 'application'
-
-group = groupName
-version = versionNumber
-
-//application allows the Task 'run' which runs the main class
-mainClassName = "de.tu_darmstadt.tk.SmartHomeNetworkSim.Main"
-
-repositories {
-	jcenter()
-}
-
-//Creates the Jar
-jar {
-    manifest {
-        attributes 'Main-Class': 'de.tu_darmstadt.tk.SmartHomeNetworkSim.Main'
-    }
-}
-
-test {
-	ignoreFailures = true
-}
-
-//Runs the created Jar
-task runIt(dependsOn:jar) {
-    doLast {
-        javaexec { 
-            main="-jar"; args jar.archivePath
-        }
-    }
-}
-
-dependencies {
-	compile 'org.pcap4j:pcap4j-core:1.+'
-	compile 'org.pcap4j:pcap4j-packetfactory-static:1.+'
-
-	testCompile 'junit:junit:4.12'
-}
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * This is a general purpose Gradle build.
+ * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/
+ */
+
+apply plugin: 'java'
+apply plugin: 'eclipse'
+apply plugin: 'application'
+
+group = groupName
+version = versionNumber
+
+//application allows the Task 'run' which runs the main class
+mainClassName = "de.tu_darmstadt.tk.SmartHomeNetworkSim.Main"
+
+repositories {
+	jcenter()
+}
+
+//Creates the Jar
+jar {
+    manifest {
+        attributes 'Main-Class': 'de.tu_darmstadt.tk.SmartHomeNetworkSim.Main'
+    }
+}
+
+test {
+	ignoreFailures = true
+}
+
+//Runs the created Jar
+task runIt(dependsOn:jar) {
+    doLast {
+        javaexec { 
+            main="-jar"; args jar.archivePath
+        }
+    }
+}
+
+dependencies {
+	compile 'org.pcap4j:pcap4j-core:1.+'
+	compile 'org.pcap4j:pcap4j-packetfactory-static:1.+'
+	// https://mvnrepository.com/artifact/org.apache.commons/commons-math3
+	compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
+	//compile group: 'nz.ac.waikato.cms.weka', name: 'weka-stable', version: '3.8.0'
+	compile fileTree(include: ['*.jar'], dir: 'libs')
+	
+	testCompile 'junit:junit:4.12'
+}

+ 16 - 0
examples/CountingMetric.java

@@ -20,9 +20,15 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimplePa
  */
 public class CountingMetric implements PacketSniffer {
 
+	/**
+	 * Mode of the algorithm, True = testing
+	 */
+	private boolean mode = false;
+	
 	@Override
 	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
 		System.out.println("Counting Metric: ");
+		System.out.println("Mode: "+(mode?"Testing":"Training"));
 		if(packets==null)return;
 		/**
 		 * Print all links and their number of packets sent
@@ -133,4 +139,14 @@ public class CountingMetric implements PacketSniffer {
 		
 		
 	}
+	
+	@Override
+	public void setMode(boolean testing) {
+		mode = testing;
+	}
+	
+	@Override
+	public boolean getMode() {
+		return mode;
+	}
 }

+ 307 - 0
examples/UnsupervisedAnomalyDetectionExample.java

@@ -0,0 +1,307 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map.Entry;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
+import weka.clusterers.SimpleKMeans;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Example - maybe Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class UnsupervisedAnomalyDetectionExample implements PacketSniffer {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+	
+	/**
+	 * True, if instances should be used for training
+	 */
+	private boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	private ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	private Instances dataset;
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	private HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Number of Clusters
+	 */
+	private int NUMBER_OF_CLUSTERS = 2;
+	
+	/**
+	 * Number of packets used for number of packets per second
+	 */
+	private int NUMBER_OF_PACKETS = 30;
+	
+	/**
+	 * 
+	 */
+	private HashMap<String,Integer> link_mappings = new HashMap<String, Integer>();
+
+	private HashMap<String,Integer> source_mappings = new HashMap<String, Integer>();
+	
+	private HashMap<String,Integer> destination_mappings = new HashMap<String, Integer>();
+	
+	private HashMap<String,Integer> protocol_mappings = new HashMap<String, Integer>();
+	/**
+	 * 
+	 */
+	public UnsupervisedAnomalyDetectionExample() {
+		// Initialize Attribute list
+		link_mappings.put("unknown", 0);
+		atts.add(new Attribute("Link-Name", false));//TODO:??
+		source_mappings.put("unknown", 0);
+		atts.add(new Attribute("Source-Device", false));
+		atts.add(new Attribute("Source-Port-number", false));
+		destination_mappings.put("unknown", 0);
+		atts.add(new Attribute("Destination-Device", false));
+		atts.add(new Attribute("Destination-Port-number", false));
+		protocol_mappings.put("unknown", 0);
+		atts.add(new Attribute("Protocol-name", false));
+		atts.add(new Attribute("Packets-per-second", false));
+		// Initialize data set
+		dataset = new Instances("Packets", atts, 100000);
+		// Initialize Clusterer
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		try {
+			clusterer.setNumClusters(NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+	
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	private double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	private Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, link == null ? 0 : stringToNumber(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, 0);
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, 0);
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNumber(source_mappings, packet.getSource().getOwner().getName()));
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, 0);
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, 0);
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNumber(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNumber(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		
+		return instance;
+	}
+	
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	double stringToNumber(HashMap<String, Integer> map, String s) {
+		Integer i = map.get(s);
+		if(i == null) {
+			int size = map.size();
+			map.put(s, size);
+			return size;
+		}else {
+			return i;
+		}
+	}
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	private void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	private void finishDataCollection() throws Exception{
+		/**
+		 * Build the clusterer for the given dataset
+		 */
+		clusterer.buildClusterer(dataset);
+	}
+	
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	private void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				try {
+					/**
+					 * Try to classify (find appropriate cluster)
+					 */
+					clusterer.clusterInstance(packet_instance);
+				} catch (Exception e) {
+					/**
+					 * Anomaly found
+					 */
+					System.out.println("Anomaly: "+packet.getTextualRepresentation());
+					//e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			// Build Clusterer
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+}

+ 343 - 0
examples/UnsupervisedAnomalyDetectionExample2.java

@@ -0,0 +1,343 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map.Entry;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
+import weka.clusterers.SimpleKMeans;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Example - maybe Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class UnsupervisedAnomalyDetectionExample2 implements PacketSniffer {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+	
+	/**
+	 * True, if instances should be used for training
+	 */
+	private boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	private ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	private Instances dataset;
+	
+	/**
+	 * CollectedPackets
+	 */
+	private HashMap<Link, LinkedList<Packet>> collectedPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	private HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Number of Clusters
+	 */
+	private int NUMBER_OF_CLUSTERS = 2;
+	
+	/**
+	 * Number of packets used for number of packets per second
+	 */
+	private int NUMBER_OF_PACKETS = 30;
+	
+	/**
+	 * 
+	 */
+	private HashSet<String> link_mappings = new HashSet<String>();
+
+	private HashSet<String> source_mappings = new HashSet<String>();
+	
+	private HashSet<String> destination_mappings = new HashSet<String>();
+	
+	private HashSet<String> protocol_mappings = new HashSet<String>();
+	
+	/**
+	 * 
+	 */
+	public UnsupervisedAnomalyDetectionExample2() {
+		// Initialize Attribute list
+		source_mappings.add("unknown");
+		link_mappings.add("unknown");
+		destination_mappings.add("unknown");
+		protocol_mappings.add("unknown");
+		// Initialize data set
+		// Initialize Clusterer
+
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		try {
+			clusterer.setNumClusters(NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	private double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	private Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, stringToNominal(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, "unknown");
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, "unknown");
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNominal(source_mappings, packet.getSource().getOwner().getName()));
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, "unknown");
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, "unknown");
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNominal(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNominal(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		
+		return instance;
+	}
+	
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	String stringToNominal(HashSet<String> map, String s) {
+		return map.contains(s)?s:"unknown";
+	}
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	private void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for(Entry<Link, LinkedList<Packet>> e:packets.entrySet()) {
+			Link l = e.getKey();
+			LinkedList<Packet> p = collectedPackets.get(l);
+			if(p == null)
+				collectedPackets.put(l, new LinkedList<Packet>(e.getValue()));
+			else
+				p.addAll(e.getValue());
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	private void finishDataCollection() throws Exception{
+		atts.add(new Attribute("Link-Name", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("Source-Device", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("Source-Port-number", false));
+		atts.add(new Attribute("Destination-Device", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("Destination-Port-number", false));
+		Attribute pn = new Attribute("Protocol-name", new LinkedList<String>(protocol_mappings));
+		//pn.setWeight(10);
+		atts.add(pn);
+		Attribute pps = new Attribute("Packets-per-second", false);
+		//pps.setWeight(20);
+		atts.add(pps);
+		//atts.add(new Attribute("Anomaly", false));
+
+		/*
+		atts = new ArrayList<Attribute>();
+		atts.add(new Attribute("LN", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("SD", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("SPN", false));
+		atts.add(new Attribute("DD", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("DPN", false));
+		atts.add(new Attribute("PN", new LinkedList<String>(protocol_mappings)));
+		atts.add(new Attribute("PPS", false));
+		atts.add(new Attribute("A", false));*/
+		dataset = new Instances("Packets", atts, 100000);
+		//dataset.setClassIndex(7);
+
+		/**
+		 * Add Instances to dataset
+		 */
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = collectedPackets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+		
+		/**
+		 * Build the clusterer for the given dataset
+		 */
+		clusterer.buildClusterer(dataset);
+	}
+	
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	private void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				
+				if(packet_instance == null)continue;
+				try {
+					/**
+					 * Try to classify (find appropriate cluster)
+					 */
+					int c = clusterer.clusterInstance(packet_instance);
+					System.out.println("Cluster "+c+": "+packet.getTextualRepresentation());
+				} catch (Exception e) {
+					/**
+					 * Anomaly found
+					 */
+					System.out.println("Anomaly: "+packet.getTextualRepresentation());
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			// Build Clusterer
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+}

+ 426 - 0
examples/classifier/BasicPacketClassifier.java

@@ -0,0 +1,426 @@
+package classifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map.Entry;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketSniffer;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTTpublishPacket;
+import weka.core.Attribute;
+import weka.core.DenseInstance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Unsupervised Classifier Basis, which contains methods for transforming {@link Packet}s into {@link Instance}s.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public abstract class BasicPacketClassifier implements PacketSniffer {
+
+	/**
+	 * True, if instances should be used for training
+	 */
+	protected boolean training = true;
+	
+	/**
+	 * Attributes which should be taken into account
+	 */
+	protected ArrayList<Attribute> atts = new ArrayList<Attribute>();
+	
+	/**
+	 * Collected Packets
+	 */
+	protected Instances dataset;
+	
+	/**
+	 * CollectedPackets
+	 */
+	protected HashMap<Link, LinkedList<Packet>> collectedPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * HashMap for calculating transmission delay
+	 */
+	protected HashMap<Link, LinkedList<Packet>> lastPackets = new HashMap<Link, LinkedList<Packet>>();
+	
+	/**
+	 * Map for the different Link names
+	 */
+	protected HashSet<String> link_mappings = new HashSet<String>();
+
+	/**
+	 * Map for the difference source device names
+	 */
+	protected HashSet<String> source_mappings = new HashSet<String>();
+	
+	/**
+	 * Map for the different destination device names
+	 */
+	protected HashSet<String> destination_mappings = new HashSet<String>();
+	
+	/**
+	 * Map for the protocol names
+	 */
+	protected HashSet<String> protocol_mappings = new HashSet<String>();
+
+	/**
+	 * Number of packets which are used to calculate the current transmission speed
+	 */
+	protected int NUMBER_OF_PACKETS = 200;
+	
+	/**
+	 * Initializes the different maps
+	 */
+	public BasicPacketClassifier() {
+		// Initialize Attribute list
+		source_mappings.add("unknown");
+		link_mappings.add("unknown");
+		destination_mappings.add("unknown");
+		protocol_mappings.add("unknown");
+	}
+	
+	@Override
+	public void processPackets(HashMap<Link, LinkedList<Packet>> packets) {
+		if(training)
+			try {
+				training(packets);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		else
+			classify(packets);
+	}
+	
+	/**
+	 * Estimates the current Packets per second (depending on the last 100 packets of the link)
+	 * @param link Link which should be checked
+	 * @param packet Packet which should investigated
+	 * @return estimated number of packets per second
+	 */
+	protected double getEstimatedPacketsPerSecond(Link link, Packet packet) {
+		/**
+		 * Packets used to calculated the packets per second
+		 */
+		LinkedList<Packet> list = lastPackets.get(link);
+		if(list == null) {
+			/**
+			 * Add list if not present
+			 */
+			list = new LinkedList<Packet>();
+			lastPackets.put(link, list);
+		}
+		if(list.isEmpty()) {
+			list.addLast(packet);
+			// Default 1 packet per second
+			return 1.0;
+		}
+		if(list.size() == NUMBER_OF_PACKETS){
+			list.removeFirst();	
+		}
+		list.addLast(packet);
+		/**
+		 * elapsed time in milliseconds since last packet
+		 */
+		long elapsed_time = packet.getTimestamp()-list.getFirst().getTimestamp()/list.size();
+		if(elapsed_time<=0)
+			return Double.POSITIVE_INFINITY;
+		/**
+		 * Return number of packets per second
+		 */
+		return 1000.0/elapsed_time;
+		
+	}
+	
+	/**
+	 * Returns the instance representation of the given packet and link
+	 * @param link link the packet was sent on
+	 * @param packet packet which should be transformed
+	 * @param dataset distribution the packet is part of
+	 * @return instance representation
+	 */
+	protected Instance packet2Instance(Link link, Packet packet, Instances dataset) {
+		/**
+		 * Instance for the given Packet
+		 */
+		DenseInstance instance = new DenseInstance(dataset.numAttributes());
+		instance.setDataset(dataset);
+		
+		// link
+		instance.setValue(0, stringToNominal(link_mappings, link.getName()));
+		
+		// source
+		if(packet.getSource()==null) {
+			instance.setValue(1, "unknown");
+			instance.setValue(2, Double.NEGATIVE_INFINITY);
+		}else if(packet.getSource().getOwner()==null){
+			instance.setValue(1, "unknown");
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}else {
+			instance.setValue(1, stringToNominal(source_mappings, packet.getSource().getOwner().getName()));
+
+			instance.setValue(2, packet.getSource().getPortNumber());
+		}
+		
+		// Destination
+		if(packet.getDestination()==null) {
+			instance.setValue(3, "unknown");
+			instance.setValue(4, Double.NEGATIVE_INFINITY);
+		}else if(packet.getDestination().getOwner()==null){
+			instance.setValue(3, "unknown");
+
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}else {
+			instance.setValue(3, stringToNominal(destination_mappings, packet.getDestination().getOwner().getName()));
+			instance.setValue(4, packet.getDestination().getPortNumber());
+		}
+		
+		// Protocol name
+		instance.setValue(5, stringToNominal(protocol_mappings, packet.getProtocolName()));
+		
+		// Packets per second
+		instance.setValue(6, getEstimatedPacketsPerSecond(link, packet));
+		// MQTT Value
+		if(packet instanceof MQTTpublishPacket)
+			instance.setValue(7, ((MQTTpublishPacket)packet).getValue());
+		else
+			instance.setValue(7, -1);
+		
+		return instance;
+	}
+	
+	/**
+	 * Inserts the
+	 * @param map
+	 * @param nominal
+	 */
+	protected void insertNominalIntoMap(HashSet<String> map, String nominal) {
+		if(map == null || nominal == null)
+			return;
+		map.add(nominal);
+	}
+	/**
+	 * Transforms the String into an Number
+	 * @param map
+	 * @param s
+	 * @return
+	 */
+	protected String stringToNominal(HashSet<String> map, String s) {
+		return map.contains(s)?s:"unknown";
+	} 
+	
+	/**
+	 * Train the clusterer by collecting the packets
+	 * 
+	 * @param packets packets to be learned
+	 */
+	protected void training(HashMap<Link, LinkedList<Packet>> packets) {
+		for(Entry<Link, LinkedList<Packet>> e:packets.entrySet()) {
+			Link l = e.getKey();
+			// TODO: ERROR ????????
+			LinkedList<Packet> p = collectedPackets.get(l);
+			if(p == null) {
+				collectedPackets.put(l, new LinkedList<Packet>(e.getValue()));
+			} else
+				p.addAll(e.getValue());
+			insertNominalIntoMap(link_mappings, l.getName());
+			for(Packet pac: e.getValue()) {
+				if(pac == null || pac.getSource()==null ||pac.getDestination() == null || pac.getSource().getOwner() == null || pac.getDestination().getOwner() == null)
+					continue;
+				insertNominalIntoMap(destination_mappings, pac.getSource().getOwner().getName());
+				insertNominalIntoMap(destination_mappings, pac.getDestination().getOwner().getName());
+				insertNominalIntoMap(source_mappings, pac.getSource().getOwner().getName());
+				insertNominalIntoMap(source_mappings, pac.getDestination().getOwner().getName());
+				insertNominalIntoMap(protocol_mappings, pac.getProtocolName());
+			}
+			//TODO: Add packet/Link/Names etc. to mappings
+		}
+	}
+	
+	/**
+	 * Finishes the collection and trains the clusterer on the collected packets
+	 * 
+	 * @throws Exception
+	 */
+	protected void finishDataCollection() throws Exception{
+		/**
+		printHashSet("Link-Name", link_mappings);
+		printHashSet("Source-Device", source_mappings);
+		printHashSet("Destination-Port", destination_mappings);
+		printHashSet("Protocol-name", protocol_mappings);
+		*/
+		atts.add(new Attribute("Link-Name", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("Source-Device", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("Source-Port-number", false));
+		atts.add(new Attribute("Destination-Device", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("Destination-Port-number", false));
+		Attribute pn = new Attribute("Protocol-name", new LinkedList<String>(protocol_mappings));
+		//pn.setWeight(10);
+		atts.add(pn);
+		Attribute pps = new Attribute("Packets-per-second", false);
+		//pps.setWeight(20);
+		atts.add(pps);
+		atts.add(new Attribute("PacketValue", false));
+		//atts.add(new Attribute("Anomaly", false));
+
+		/*
+		atts = new ArrayList<Attribute>();
+		atts.add(new Attribute("LN", new LinkedList<String>(link_mappings)));//TODO:??
+		atts.add(new Attribute("SD", new LinkedList<String>(source_mappings)));
+		atts.add(new Attribute("SPN", false));
+		atts.add(new Attribute("DD", new LinkedList<String>(destination_mappings)));
+		atts.add(new Attribute("DPN", false));
+		atts.add(new Attribute("PN", new LinkedList<String>(protocol_mappings)));
+		atts.add(new Attribute("PPS", false));
+		atts.add(new Attribute("A", false));*/
+		dataset = new Instances("Packets", atts, 100000);
+		//dataset.setClassIndex(7);
+
+		/**
+		 * Add Instances to dataset
+		 */
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = collectedPackets.entrySet().iterator(); it.hasNext();) {
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packet was captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packets to be added to the dataset
+				 */
+				Packet packet = (Packet) itPacket.next();
+				dataset.add(packet2Instance(l, packet, dataset));
+			}
+		}
+		
+		trainModel(dataset);
+	}
+	
+	private void printHashSet(String name, HashSet<String> toPrint) {
+		System.out.println(name+":");
+		for (Iterator<String> iterator = toPrint.iterator(); iterator.hasNext();) {
+			String string = (String) iterator.next();
+			System.out.print(string);
+			if(iterator.hasNext())
+				System.out.print(", ");
+		}
+		System.out.println();
+	}
+	/**
+	 * Try to classify the given packets and detect anomalies
+	 * @param packets packets to be classified
+	 */
+	protected void classify(HashMap<Link, LinkedList<Packet>> packets) {
+		int tp = 0;
+		int fp = 0;
+		int tn = 0;
+		int fn = 0;
+		long start = Long.MAX_VALUE;
+		long end = Long.MIN_VALUE;
+		for (Iterator<Entry<Link, LinkedList<Packet>>> it = packets.entrySet().iterator(); it.hasNext();) {
+			/**
+			 * Link & its packets
+			 */
+			Entry<Link, LinkedList<Packet>> entry = it.next();
+			/**
+			 * Link the packets were captured on
+			 */
+			Link l = entry.getKey();
+			for (Iterator<Packet> itPacket = entry.getValue().iterator(); itPacket.hasNext();) {
+				/**
+				 * Packet which should be checked
+				 */
+				Packet packet = (Packet) itPacket.next();
+
+				start = Math.min(start, packet.getTimestamp());
+				end = Math.max(end, packet.getTimestamp());
+				/**
+				 * Instance Representation
+				 */
+				Instance packet_instance = packet2Instance(l, packet, dataset);
+				
+				if(packet_instance == null)continue;
+				try {
+					double dist = classifyInstance(packet_instance, packet);	
+					if(dist<=1.0) {
+						if(packet.getLabel()==0)
+							tn++;
+						else
+							fn++;
+					}else {
+						if(packet.getLabel()==0)
+							fp++;
+						else
+							tp++;
+					}
+				} catch (Exception e) {
+					if(packet.getLabel()==0)
+						fp++;
+					else
+						tp++;
+				}
+			}	
+		}
+		int n = tp+tn+fp+fn;
+		if(n!=0) {
+			System.out.println(getAlgoName()+" Performance: ["+start+"ms, "+end+"ms]");
+			System.out.println("n: "+n);
+			System.out.println("TP: "+tp);
+			System.out.println("FP: "+fp);
+			System.out.println("TN: "+tn);
+			System.out.println("FN: "+fn);
+			System.out.println("TPR: "+(tp/(tp+fn+0.0)));
+			System.out.println("FPR: "+(fp/(fp+tn+0.0)));
+			System.out.println("");
+		}
+	}
+	
+	/**
+	 * Train the model using the given instances
+	 * @param instances training set, which should be learned
+	 */
+	public abstract void trainModel(Instances instances);
+	
+	/**
+	 * classifies the given instance
+	 * @param instance instance which should be classified
+	 * @param origin original packet, which was transformed into the instance
+	 * @return distance to next centroid
+	 * @throws Exception if anomaly was detected
+	 */
+	public abstract double classifyInstance(Instance instance, Packet origin) throws Exception;
+	
+	/**
+	 * Returns the timestep, after which the classifier should start classifying instead of training.
+	 * @return timestep of the testing begin.
+	 */
+	public abstract long getClassificationStart();
+	
+	@Override
+	public void setMode(boolean testing) {
+		training = !testing;
+		if(testing) {
+			try {
+				finishDataCollection();
+			} catch (Exception e) {
+				System.out.println("Clustering failed");
+				e.printStackTrace();
+			}	
+		}
+	}
+	
+	@Override
+	public boolean getMode() {
+		return !training;
+	}
+	
+	/**
+	 * Short String representation of the classifier
+	 * @return
+	 */
+	public abstract String getAlgoName();
+}

+ 87 - 0
examples/classifier/EMClustering.java

@@ -0,0 +1,87 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.EM;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Expectation Maximization Clustering Approach
+ * @author Andreas T. Meyer-Berg
+ */
+public class EMClustering extends BasicPacketClassifier {
+
+	/**
+	 * EM cluster which is used
+	 */
+	private EM clusterer;
+	
+	/**
+	 * Initialize the clusterer
+	 */
+	public EMClustering() {
+		clusterer = new EM();
+	}
+	
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closest cluster
+		 */
+		int x = clusterer.clusterInstance(instance);
+
+		/*
+		System.out.println(origin.getTextualRepresentation()+": cluster: "+x+" Dens: "+clusterer.logDensityForInstance(instance)+" joined: ");
+		double[] joined = clusterer.logJointDensitiesForInstance(instance);
+		for(int i = 0;i<joined.length;) {
+			System.out.print(joined[i]);
+			if(++i<joined.length)
+				System.out.print(", ");
+			else
+				System.out.println("");
+		}
+		System.out.println("Distribution:");
+		double[] distribution = clusterer.distributionForInstance(instance);
+		for(int i = 0;i<distribution.length;) {
+			System.out.print(distribution[i]);
+			if(++i<distribution.length)
+				System.out.print(", ");
+			else
+				System.out.println("");
+		}
+		
+		double[] priors = clusterer.clusterPriors();
+		System.out.println("Priors: ");
+		for(int i = 0; i<priors.length; i++) {
+			System.out.println("i="+i+": "+priors[i]);
+		}
+		double[][][] rest = clusterer.getClusterModelsNumericAtts();
+		double[][] posteriori = rest[x];
+		for(int i = 0; i<posteriori.length; i++) {
+			System.out.println("Att "+i+": Mean: "+posteriori[i][0]+" Std: "+posteriori[i][1]+" ???: "+posteriori[i][2]+" Real: "+instance.value(i));
+		}*/
+		return (1-clusterer.distributionForInstance(instance)[x])*800;
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "EM";
+	}
+
+}

+ 70 - 0
examples/classifier/HierarchicalClustering.java

@@ -0,0 +1,70 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.HierarchicalClusterer;
+import weka.core.EuclideanDistance;
+import weka.core.Instance;
+import weka.core.Instances;
+
+/**
+ * Hierarchical Clustering Approach
+ * @author Andreas T. Meyer-Berg
+ */
+public class HierarchicalClustering extends BasicPacketClassifier {
+
+	/**
+	 * Hierarchical cluster which is used
+	 */
+	private HierarchicalClusterer clusterer;
+	
+	/**
+	 * Initialize the clusterer
+	 */
+	public HierarchicalClustering() {
+		clusterer = new HierarchicalClusterer();
+		clusterer.setDistanceFunction(new EuclideanDistance());
+		clusterer.setNumClusters(16);
+	}
+	
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closes cluster centroid
+		 */
+		int x = clusterer.clusterInstance(instance);
+		/**
+		 * centroid instance
+		 */
+		/*
+		System.out.print(origin.getTextualRepresentation()+": ");
+		double[] posteriori = clusterer.distributionForInstance(instance);
+		for(int i = 0; i<posteriori.length; i++) {
+			System.out.print(posteriori[i]);
+			if(i<posteriori.length-1)
+				System.out.print(", ");
+		}*/
+		return 1;
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "HC";
+	}
+
+}

+ 121 - 0
examples/classifier/KMeansClustering.java

@@ -0,0 +1,121 @@
+package classifier;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import weka.clusterers.SimpleKMeans;
+import weka.core.Instance;
+import weka.core.Instances;
+import weka.core.SelectedTag;
+
+/**
+ * Unsupervised Example: K Means Clustering
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class KMeansClustering extends BasicPacketClassifier {
+
+	/**
+	 * Clusterer
+	 */
+	private SimpleKMeans clusterer;
+
+	/**
+	 * Number of Clusters
+	 */ 
+	//17 works fine
+	//34 found value anomalies
+	protected int NUMBER_OF_CLUSTERS = 34;
+	protected double[] stdv = new double[NUMBER_OF_CLUSTERS];
+	/**
+	 * Initializes the k means clusterer
+	 */
+	public KMeansClustering() {
+		super();
+		clusterer = new SimpleKMeans();
+		clusterer.setSeed(42);
+		//clusterer.setDisplayStdDevs(true);
+		clusterer.setInitializationMethod(new SelectedTag(SimpleKMeans.FARTHEST_FIRST,SimpleKMeans.TAGS_SELECTION));
+		//clusterer.setCanopyPeriodicPruningRate(100);
+		//clusterer.setCanopyT1(0.001);
+		//clusterer.setCanopyT2(0.1);
+		try {
+			clusterer.setNumClusters(this.NUMBER_OF_CLUSTERS);
+		} catch (Exception e) {
+			System.out.println("Error while building cluster");
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void trainModel(Instances instances) {
+		try {
+			clusterer.buildClusterer(instances);
+			double[] sumOfSquares = new double[NUMBER_OF_CLUSTERS];
+			for(Instance i: instances) {
+				/**
+				 * Id of the closest cluster centroid
+				 */
+				int x = clusterer.clusterInstance(i);
+				/**
+				 * centroid instance
+				 */
+				Instance center = clusterer.getClusterCentroids().get(x);
+				/**
+				 * Distance
+				 */
+				double dist = clusterer.getDistanceFunction().distance(center, i);
+				sumOfSquares[x] += dist*dist;
+			}
+			/**
+			 * Calculate Standard Deviations
+			 */
+			for(int i = 0; i<NUMBER_OF_CLUSTERS; i++)
+				this.stdv[i] = Math.sqrt(sumOfSquares[i]);
+		} catch (Exception e) {
+			System.out.println("Failed while training the classifier");
+			e.printStackTrace();
+		}
+	}
+	private boolean test = true;
+	@Override
+	public double classifyInstance(Instance instance, Packet origin) throws Exception {
+		/**
+		 * Id of the closest cluster centroid
+		 */
+		int x = clusterer.clusterInstance(instance);
+		/**
+		 * centroid instance
+		 */
+		Instance center = clusterer.getClusterCentroids().get(x);
+		
+		double dist = clusterer.getDistanceFunction().distance(center, instance);
+		if(test && dist<stdv[x] && origin.getLabel()!=0) {
+			test = false;
+			System.out.println("Analysis of: "+origin.getTextualRepresentation());
+			System.out.println("Classified as: "+x+" Dist: "+dist+" Stdv: "+stdv[x]);
+			for(int i=0; i<NUMBER_OF_CLUSTERS; i++) {
+				Instance centroid = clusterer.getClusterCentroids().get(i);
+				if(centroid == null)continue;
+				double d = clusterer.getDistanceFunction().distance(centroid, instance);
+				
+				System.out.println("Cluster: "+i+" Dist: "+d+" Stdv: "+stdv[i]);
+			}
+			test = false;
+			System.out.println("");
+		}
+		if(dist < stdv[x])
+			return 0;
+		else
+			return Double.MAX_VALUE;
+		
+	}
+
+	@Override
+	public long getClassificationStart() {
+		return 3600000;
+	}
+
+	@Override
+	public String getAlgoName() {
+		return "KNN";
+	}
+}

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists

BIN
libs/weka.jar


BIN
libs_src/weka_src.jar


+ 196 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ExampleAnomalyController.java

@@ -0,0 +1,196 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleProtocol;
+
+/**
+ * Controller, which allows the user to create a few example anomalies
+ * @author Andreas T. Meyer-Berg
+ *
+ */
+public class ExampleAnomalyController {
+
+	/**
+	 * Controller which is used to manipulates the network parts
+	 */
+	private Controller controller;
+	
+	/**
+	 * Initializes the Anomaly Controller
+	 * @param controller controller to be used
+	 */
+	public ExampleAnomalyController(Controller controller) {
+		this.controller = controller;
+	}
+	
+	/**
+	 * Opens a DDosCreation Menu which targets the given Device
+	 * So far only a DDoS Attack is created
+	 * @param d Device which should be targeted
+	 * @return DDoS Connection, which was created 
+	 */
+	public Connection openDDosCreationMenu(SmartDevice d, List<SmartDevice> sources) {
+		/**
+		 * Port of the largest connected connection to disguise DDoS
+		 */
+		Port example = null;
+		for(Port p: d.getPorts()) {
+			if(example == null || example.getConnection() == null || example.getConnection().getProtocol()==null) {
+				example = p;
+			} else {
+				if(p.getConnection() == null || p.getConnection().getProtocol() == null) {
+					continue;
+				} else if(p.getConnection().getParticipants().size()>example.getConnection().getParticipants().size()){
+					example = p;
+				}
+			}
+		}
+		if(example == null || example.getConnection() == null || example.getConnection().getProtocol()==null)
+			example = null;
+		/**
+		 * Role of the target device
+		 */
+		int targetRole = 0;
+		if(example != null) {
+			targetRole = example.getConnection().getProtocol().getRoleOfDevice(example);
+			if(targetRole == -1)
+				targetRole = 0;
+		}
+		/**
+		 * Attack Interval per device
+		 */
+		long attackInterval = 1;
+		if(example!=null) {
+			int numDevices = 0;
+			for(Port exP:example.getConnection().getParticipants()) {
+				attackInterval+=exP.getTriggerInterval();
+				numDevices++;
+			}
+			attackInterval /= numDevices == 0 ? 1 : numDevices;
+			/**
+			 * Frequency Less or equal
+			 */
+			attackInterval /= 10.0;
+		}
+		
+		/**
+		 * Link of the DDoS attack
+		 */
+		Link link = null;
+		if(example !=null)
+			link = example.getConnection().getLink();
+		if(link == null) {
+			if(d.getLinks().isEmpty()) {
+				System.out.println("WARNING: Could not create DDos, as Device "+d.getName()+" is not connected to any Link");
+				return null;
+			}
+			link = d.getLinks().get(0);
+		}
+		NetworkController networkController = controller.getNetworkController();
+		Connection ddosConnection = new ConnectionPrecision();
+		ddosConnection.setLabel((short)1);
+		ddosConnection.setName("DDOS against "+d.getName());
+		networkController.addConnectionToLink(ddosConnection, link);
+		try {
+			@SuppressWarnings("unchecked")
+			Class<Protocol> exampleProtocol = (Class<Protocol>) example.getConnection().getProtocol().getClass();
+			ddosConnection.setProtocol(exampleProtocol.newInstance());	
+		} catch (Exception e) {
+			ddosConnection.setProtocol(new SimpleProtocol());			
+		}
+		LinkedList<SmartDevice> devices = new LinkedList<SmartDevice>(sources);
+		devices.retainAll(link.getDevices());
+		
+		
+		Port pTarget = new Port(d, (short)80, 1000L);
+		pTarget.setStatus(Port.OPEN);
+		if(!networkController.addDeviceToConnectionAndProtocol(pTarget, ddosConnection, targetRole)) {
+			System.out.println("WARNING: Could not add DDoS Target to role "+targetRole);
+		}
+			
+		for(SmartDevice src: devices) {
+			if(src==d)continue;
+			Port pSource = new Port(src, (short)80, 1L);
+			pSource.setTriggerHandler(new NormalDistributionHandler(attackInterval, attackInterval*0.05));
+			pSource.setStatus(Port.SENDING);
+			// Ten tries of assigning random role
+			for(int i=0; i<10;i++) {
+				int sourceRole = (int) Math.floor(Math.random()*ddosConnection.getProtocol().getNumberOfRoles());
+				if(sourceRole==targetRole)
+					continue;
+				if(networkController.addDeviceToConnectionAndProtocol(pSource, ddosConnection, sourceRole)) 
+					break;
+			}
+		}
+		networkController.addConnection(ddosConnection);
+		
+		controller.notifyObservers();
+		return ddosConnection;
+	}
+	
+	/**
+	 * Crash Device, which wont send packets any longer
+	 * @param d Device to be crashed
+	 */
+	public void crashDevice(SmartDevice d) {
+		for(Port p:d.getPorts()) {
+			p.setStatus(Port.CLOSED);
+		}
+		controller.notifyObservers();
+	}
+
+	/**
+	 * Inserts DOS attack into the network
+	 * @param source source of the attack
+	 * @param target destination of the attack
+	 * @return DDoS Connection, which was created
+	 */
+	public Connection runDosAttack(SmartDevice source, SmartDevice target) {
+		NetworkController networkController = controller.getNetworkController();
+		Connection dosConnection = new ConnectionPrecision();
+		dosConnection.setLabel((short)1);
+		dosConnection.setName("DOS: "+source.getName()+"-"+target.getName());
+		networkController.addConnectionToLink(dosConnection, getCommonLink(source, target));
+		dosConnection.setProtocol(new SimpleProtocol());
+		Port pSource = new Port(source, (short)80, 4L);
+		pSource.setStatus(Port.SENDING);
+		networkController.addDeviceToConnectionAndProtocol(pSource, dosConnection, 0);
+		Port pTarget = new Port(target, (short)80, 1000L);
+		pTarget.setStatus(Port.OPEN);
+		networkController.addDeviceToConnectionAndProtocol(pSource, dosConnection, 0);
+		networkController.addDeviceToConnectionAndProtocol(pTarget, dosConnection, 1);
+		networkController.addConnection(dosConnection);
+		controller.notifyObservers();
+		return dosConnection;
+	}
+	
+	/**
+	 * Returns a common Link of the given devices
+	 * @param a
+	 * @param b
+	 * @return Link, both devices are connected to
+	 */
+	private Link getCommonLink(SmartDevice a, SmartDevice b) {
+		LinkedList<Link> l = new LinkedList<Link>(a.getLinks());
+		l.addAll(b.getLinks());
+		if(l.isEmpty()) {
+			NetworkController net = controller.getNetworkController();
+			Link newLink = new PrecisionLink("Direct Link: " + a.getName()+"-"+b.getName());
+			net.addLinkToDevice(newLink, a);
+			net.addLinkToDevice(newLink, b);
+			net.addLink(newLink);
+			return newLink;
+		}else
+			return l.getFirst();
+	}
+}

+ 61 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java

@@ -15,6 +15,7 @@ import javax.tools.ToolProvider;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration.ImportConfiguration;
@@ -293,6 +294,66 @@ public class ImportController {
 		return true;
 	}
 	
+	/**
+	 * Adds new DistributionHandler to the model
+	 * 
+	 * @param distributionHandler DistributionHandler to be added
+	 * @return true if it was added
+	 */
+	public boolean addDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		if (isValidDistributionHandler(distributionHandler))
+			importConf.addDistributionHandlerClass(distributionHandler);
+		else
+			return false;
+		return true;
+		
+	}
+	
+	/**
+	 * Removes DistributionHandler from the model
+	 * 
+	 * @param distributionHandler
+	 *            DistributionHandler to be removed
+	 */
+	public void removeDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		importConf.removeDistributionHandlerClass(distributionHandler);
+	}
+	
+	/**
+	 * Returns the available DistributionHandler of the model
+	 * 
+	 * @return available DistributionHandler
+	 */
+	public LinkedList<Class<? extends ProbabilityDistributionHandler>> getDistributionHandlers() {
+		return importConf.getDistributionHandlerClasses();
+	}
+	
+	/**
+	 * Returns true if it is a Valid DistributionHandler, false if not
+	 * 
+	 * @param distributionHandler
+	 *            DistributionHandler to be checked
+	 * @return true if it is a valid DistributionHandler
+	 */
+	public boolean isValidDistributionHandler(Class<? extends ProbabilityDistributionHandler> distributionHandler) {
+		try {
+			/**
+			 * SmartDevice to be tested
+			 */
+			ProbabilityDistributionHandler p = distributionHandler.newInstance();
+			// Empty constructor required, to create new instance
+			if (p == null)
+				throw new Exception("DistributionHandler required an empty constructor");
+			// Name shall not be null or empty string
+			if (p.getSimpleDescription() == null || p.getSimpleDescription() == "")
+				throw new Exception(
+						"DistributionHandler name shall not be null or empty string.");
+		} catch (Exception e) {
+			return false;
+		}
+		return true;
+	}
+	
 	/**
 	 * Imports the given .java File, compiles it and returns the compiled class
 	 * 

+ 22 - 2
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/NetworkController.java

@@ -38,6 +38,10 @@ public class NetworkController {
 	 * Packet Capture Controller
 	 */
 	private PacketCaptureController captureController;
+	/**
+	 * ExampleAnomalyController
+	 */
+	private ExampleAnomalyController anomalyController;
 	/**
 	 * Creates a new NetworkController, which may manipulate the given model and use the controller
 	 * @param model Model which can be manipulated
@@ -48,6 +52,7 @@ public class NetworkController {
 		this.controller = controller;
 		networkTreeSettings = controller.getSettingsController().getNetworkTreeSettingsController();
 		captureController = controller.getSimulationController().getPacketCaptureController();
+		anomalyController = new ExampleAnomalyController(controller);
 	}
 
 	/**
@@ -92,12 +97,13 @@ public class NetworkController {
 	 * @param z_pos
 	 *            position on the z-Axis
 	 */
-	public void createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
+	public SmartDevice createSmartDevice(String name, int x_pos, int y_pos, int z_pos) {
 		SmartDevice sd = new SmartDevice(name);
 		sd.setX(controller.getSettingsController().scalePos(x_pos, 1.0, controller.getSettingsController().getWidth()));
 		sd.setY(controller.getSettingsController().scalePos(y_pos, 1.0, controller.getSettingsController().getHeight()));
 		sd.setZ(controller.getSettingsController().scalePos(z_pos, 1.0, controller.getSettingsController().getDepth()));
 		model.addDevices(sd);
+		return sd;
 	}
 
 	/**
@@ -274,7 +280,7 @@ public class NetworkController {
 			link.addDevice(smartDevice);
 		}
 		
-		if(!smartDevice.getLinks().contains(smartDevice)){
+		if(!smartDevice.getLinks().contains(link)){
 			smartDevice.addLink(link);
 		}
 		
@@ -385,6 +391,8 @@ public class NetworkController {
 				connection.addSmartDevice(p);
 			if(p.getConnection()!=connection)
 				p.setConnection(connection);
+			if(!p.getOwner().getPorts().contains(p))
+				p.getOwner().addPort(p);
 			return true;
 		}else {
 			//Device could not be added -> Remove
@@ -552,6 +560,10 @@ public class NetworkController {
 			captureController.removePacketCollector(p);
 		}
 		
+		/**
+		 * Clear event queue
+		 */
+		
 		/**
 		 * Update the GUI
 		 */
@@ -764,4 +776,12 @@ public class NetworkController {
 			return newDevice;
 		}
 	}
+
+	/**
+	 * Returns the AnomalyController, which can be used to insert anomalies into the network model
+	 * @return Anomaly Controller
+	 */
+	public ExampleAnomalyController getAnomalyController() {
+		return anomalyController;
+	}
 }

+ 43 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/PacketCaptureController.java

@@ -163,7 +163,49 @@ public class PacketCaptureController {
 			notifyObservers();
 		}
 	}
-	
+	/**
+	 * Returns training or testing mode of the algorithm.
+	 * @param collector Collector which is used
+	 * @return true if testing or false if training the algorithm.
+	 */
+	public boolean getMode(PacketCollector collector) {
+		if(collector == null) 
+			return false;
+		return collector.getMode();
+	}
+
+	/**
+	 * Sets the training or testing mode
+	 * @param collector Collector which is used
+	 * @param mode true if testing or false if training the algorithm.
+	 */
+	public void setMode(PacketCollector collector, boolean mode) {
+		if(collector == null) return;
+		collector.setMode(mode);
+		notifyObservers();
+	}
+
+	/**
+	 * Whether the algorithm should run
+	 * @param collector Collector which is used
+	 * @return true if algorithm will be executed
+	 */
+	public boolean isActive(PacketCollector collector) {
+		if(collector == null) 
+			return false;
+		return collector.isActive();
+	}
+
+	/**
+	 * Set to true, if it should run
+	 * @param collector Collector which is used
+	 * @param active true if it should be active
+	 */
+	public void setActive(PacketCollector collector, boolean active) {
+		if(collector == null)return;
+		collector.setActive(active);
+		notifyObservers();
+	}
 	/**
 	 * Notify all observers of the packet collection managers
 	 */

+ 20 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Connection.java

@@ -95,6 +95,7 @@ public interface Connection {
 	 *            Duration of the simulation interval in milliseconds
 	 * @return packets that were sent in this interval
 	 */
+	@Deprecated
 	public Collection<Packet> simulateTimeInterval(long startTime, long duration);
 
 	/**
@@ -107,6 +108,13 @@ public interface Connection {
 	 */
 	public Collection<Packet> getTerminationPackages(long startTime);
 
+	/**
+	 * Encapsulates the given Packets
+	 * @param packets Packets which should be encapsulated
+	 * @return Encapsulated Packets
+	 */
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets);
+	
 	/**
 	 * Returns the Protocol which is used on this Connection
 	 * 
@@ -194,4 +202,16 @@ public interface Connection {
 			return "unknown";
 		}
 	}
+	
+	/**
+	 * Returns the default label for packets of this connection represented as a short
+	 * @return default label value
+	 */
+	public short getLabel();
+	
+	/**
+	 * Set the default label value for packets of this connection
+	 * @param label new default label value
+	 */
+	public void setLabel(short label);
 }

+ 22 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPerformance.java

@@ -26,7 +26,8 @@ public class ConnectionPerformance implements Connection {
 	protected boolean changed = false;
 	/** Link on which this connection runs */
 	protected String name;
-	
+	/** default label */
+	protected short label = 0;
 	/**
 	 * Initializes the connection, adds participants of the protocol
 	 * 
@@ -105,8 +106,19 @@ public class ConnectionPerformance implements Connection {
 				returnPackets.addAll(protocol.generateNextPackets(p, (long) Math.max((p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*(Math.random())),p.getLastTrigger()+p.getTriggerInterval()),Math.random()<packetLossRate));
 		}
 		returnPackets.sort((a,b)->(Long.compare(a.getTimestamp(),b.getTimestamp())));
+		if(label!=0)
+			returnPackets.forEach(p->p.setLabel(label));
 		return returnPackets;
 	}
+	
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets) {
+		packets.forEach(p->{
+			p.setLabel((short) Math.max(Math.max(label, p.getLabel()), p.getSource().getOwner().getLabel()));
+		});
+		return packets;
+	}
+
 
 	@Override
 	public Collection<Packet> getTerminationPackages(long startTime) {
@@ -162,4 +174,13 @@ public class ConnectionPerformance implements Connection {
 		this.name = name;
 	}
 
+	@Override
+	public short getLabel() {
+		return label;
+	}
+
+	@Override
+	public void setLabel(short label) {
+		this.label = label;
+	}
 }

+ 3 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPrecision.java

@@ -120,6 +120,9 @@ public class ConnectionPrecision extends ConnectionPerformance {
 				break;
 			last = returnPackets.getLast();
 		}
+		if(label!=0)
+			returnPackets.forEach(p->p.setLabel(label));
+		
 		return returnPackets;
 	}
 	

+ 31 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Link.java

@@ -63,8 +63,33 @@ public interface Link {
 	 * @param duration
 	 *            Duration of the simulation interval in milliseconds
 	 */
+	@Deprecated
 	public void simulateTimeInterval(long startTime, long duration);
+	
+	/**
+	 * Initializes the simulation interval, by clearing the previously generated 
+	 * packets and adds Packets of previous iterations, which are are part of this interval.
+	 * @param startTime startTime of the simulation interval
+	 * @param duration duration of the simulation interval
+	 */
+	public void initSimulationInterval(long startTime, long duration);
+	
+	/**
+	 * Encapsulates the given Packets
+	 * @param packets Packets which should be encapsulated
+	 * @return Encapsulated Packets
+	 */
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets);
 
+	/**
+	 * Time at the end of an simulation interval, to remove Packets, which are not in bound, sort the array
+	 * or manipulate the packets slightly.
+	 * 
+	 * @param startTime startTime of the simulation interval
+	 * @param duration duration of the interval
+	 */
+	public void finalizeSimulationInterval(long startTime, long duration);
+	
 	/**
 	 * Returns all packets which where sent during the last Simulation time step
 	 * 
@@ -85,4 +110,10 @@ public interface Link {
 	 * @return delay of the transmission, infinite if to is unreachable or the Packets is lost.
 	 */
 	public long getTransmissionDelayFrom(SmartDevice from, SmartDevice to);
+
+	/**
+	 * Adds Packets to the internal data structure
+	 * @param packets Packets, which should be added
+	 */
+	public void addPackets(Collection<Packet> packets);
 }

+ 29 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Packet.java

@@ -21,6 +21,12 @@ public abstract class Packet {
 	 * DestinationPort of the packet
 	 */
 	protected Port destination;
+	
+	/**
+	 * Number representing the label of the package
+	 */
+	protected short label = 0;
+	
 	/**
 	 * Creates a new packet with the given timestamp
 	 * @param timestamp time the packet was sent
@@ -87,4 +93,27 @@ public abstract class Packet {
 	public Port getDestination(){
 		return destination;
 	}
+	
+	/**
+	 * Return name of the protocol, the packets is part of
+	 * 
+	 * @return Protocol name
+	 */
+	public abstract String getProtocolName();
+	
+	/**
+	 * Returns the label represented as a short
+	 * @return label value
+	 */
+	public short getLabel() {
+		return label;
+	}
+	
+	/**
+	 * Set the label value
+	 * @param label new label value
+	 */
+	public void setLabel(short label) {
+		this.label = label;
+	}
 }

+ 2 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollectionManager.java

@@ -38,6 +38,7 @@ public class PacketCollectionManager extends Observable {
 		 */
 		for(PacketCollector col: collectors){
 			col.resetPackets();
+			if(!col.isActive())continue;
 			/**
 			 * Add all links, which packets should be collected
 			 */
@@ -74,7 +75,7 @@ public class PacketCollectionManager extends Observable {
 	 */
 	public void runPacketAlgorithms(){
 		for(PacketCollector collector:collectors){
-			if(collector.getPacketAlgorithm()!=null){
+			if(collector.isActive() && collector.getPacketAlgorithm()!=null){
 				collector.getPacketAlgorithm().processPackets(collector.getPackets());
 			}
 		}

+ 46 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketCollector.java

@@ -37,6 +37,16 @@ public class PacketCollector {
 	 */
 	private PacketSniffer packetAlgorithm = null;
 	
+	/**
+	 * Mode of the Collector, whether it should train or test the packetSniffer algorithm
+	 */
+	private boolean mode = false;
+	
+	/**
+	 * True if it should collect packages
+	 */
+	private boolean active = true;
+	
 	/**
 	 * Creates a PacketCollector without assigning and algorithm to process the packets
 	 */
@@ -180,4 +190,40 @@ public class PacketCollector {
 	public void setPacketAlgorithm(PacketSniffer packetAlgorithm) {
 		this.packetAlgorithm = packetAlgorithm;
 	}
+
+	/**
+	 * Returns training or testing mode of the algorithm.
+	 * @return true if testing or false if training the algorithm.
+	 */
+	public boolean getMode() {
+		if(packetAlgorithm!=null)
+			mode = packetAlgorithm.getMode();
+		return mode;
+	}
+
+	/**
+	 * Sets the training or testing mode
+	 * @param mode true if testing or false if training the algorithm.
+	 */
+	public void setMode(boolean mode) {
+		this.mode = mode;
+		if(packetAlgorithm != null)
+			packetAlgorithm.setMode(mode);
+	}
+
+	/**
+	 * Whether the algorithm should run
+	 * @return true if algorithm will be executed
+	 */
+	public boolean isActive() {
+		return active;
+	}
+
+	/**
+	 * Set to true, if it should run
+	 * @param active true if it should be active
+	 */
+	public void setActive(boolean active) {
+		this.active = active;
+	}
 }

+ 16 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PacketSniffer.java

@@ -22,5 +22,21 @@ public interface PacketSniffer {
 	 *            grouped by each link.
 	 */
 	public void processPackets(HashMap<Link, LinkedList<Packet>> packets);
+	
+	/**
+	 * Set the mode of the algorithm, whether it should be training or testing 
+	 * with the given packets
+	 * @param testing <code>false</code> if it should be training, <code>true</code> if
+	 * it should be testing
+	 */
+	public void setMode(boolean testing);
+	
+	/**
+	 * Returns the mode of the algorithm, whether it should be training or testing 
+	 * with the given packets.<br>
+	 * <code>false</code>: if it should be training<br> 
+	 * <code>true</code>:  if it should be testing
+	 */
+	public boolean getMode();
 
 }

+ 93 - 18
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/Port.java

@@ -1,14 +1,21 @@
 package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
 
+import java.util.Collection;
 import java.util.Random;
 
+import org.apache.commons.math3.distribution.AbstractRealDistribution;
+import org.apache.commons.math3.distribution.LaplaceDistribution;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.ConstantValueDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
+
 /**
  * Representation of connection EndPoints, which allows configuration of timings
  * and if it reacts to incoming traffic or even triggers new connections.
  * 
  * @author Andreas T. Meyer-Berg
  */
-public class Port {
+public class Port implements Schedulable {
 
 	/**
 	 * A closed Port which does not react to incoming traffic
@@ -40,12 +47,6 @@ public class Port {
 	 * Connection this Port listens to
 	 */
 	private Connection connection;
-	
-	/**
-	 * Constant time interval, which triggers new traffic every
-	 * {@code triggerInterval} milliseconds.
-	 */
-	private long triggerInterval;
 
 	/**
 	 * Last timestep traffic was triggered
@@ -62,11 +63,27 @@ public class Port {
 	 */
 	private short jitter;
 	
+	/**
+	 * Current Jitter, updated after every simulation
+	 */
+	private short currentJitter;
+	
 	/**
 	 * Port number of this Port.
 	 */
 	private short portNumber;
 
+	/**
+	 * Constant time interval, which triggers new traffic every
+	 * {@code triggerInterval} milliseconds.
+	 */
+	private long triggerInterval;
+
+	/**
+	 * Probability Distribution for calculating the next Trigger
+	 */
+	private ProbabilityDistributionHandler triggerIntervalStat;
+	
 	/**
 	 * Creates a new Port for the given Device with the specified PortNumber
 	 * @param device SmartDevice this port listens on
@@ -76,9 +93,12 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		setTriggerInterval(new Random().nextInt(1000)+1);
+		triggerIntervalStat = new ConstantValueDistributionHandler(new Random().nextInt(1000)+1);
+		triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
+		//setTriggerInterval(new Random().nextInt(1000)+1);
 		lastTrigger = 0;
-		setTriggerInterval(new Random().nextInt(5)+1);
+		jitter = (short)(new Random().nextInt(5)+1);
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		responseTime = 0;
 		this.portNumber = portNumber;
 	}
@@ -93,9 +113,11 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		this.triggerInterval = triggerInterval;
+		triggerIntervalStat = new ConstantValueDistributionHandler(triggerInterval);
+		this.triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
 		lastTrigger = 0;
 		jitter = 0;
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		responseTime = 0;
 		this.portNumber = portNumber;
 	}
@@ -113,9 +135,11 @@ public class Port {
 		status = SENDING;
 		owner = device;
 		connection = null;
-		this.triggerInterval = triggerInterval;
+		triggerIntervalStat = new ConstantValueDistributionHandler(triggerInterval);
+		this.triggerInterval = Math.max(1, triggerIntervalStat.sampleNextValue());
 		this.lastTrigger = lastTrigger;
 		this.jitter = jitter;
+		currentJitter = (short)Math.round(Math.random()*jitter);
 		this.responseTime = responseTime;
 		this.portNumber = portNumber;
 	}
@@ -152,6 +176,7 @@ public class Port {
 	}
 
 	/**
+	 * TriggerInterval is sampled from distribution after previous simulation
 	 * @return the triggerInterval
 	 */
 	public long getTriggerInterval() {
@@ -159,14 +184,33 @@ public class Port {
 	}
 
 	/**
-	 * @param triggerInterval
-	 *            the triggerInterval to set
+	 * Returns the Probability Handler for the trigger interval, which allows configuration of the Distribution
+	 * @return Distribution Handler for configuration
 	 */
-	public void setTriggerInterval(long triggerInterval) {
-		if(triggerInterval<=0)
-			this.triggerInterval = (long)1;
-		else
-		    this.triggerInterval = triggerInterval;
+	public ProbabilityDistributionHandler getTriggerHandler(){
+		return triggerIntervalStat;
+	}
+	
+	/**
+	 * Set a new Probability Distribution Handler to sample the trigger interval
+	 * @param triggerHandler Sets the Probability Distribution to generate the trigger interval
+	 */
+	public void setTriggerHandler(ProbabilityDistributionHandler triggerHandler){
+		this.triggerIntervalStat = triggerHandler;
+		boolean removed = SimulationManager.removeEvent(this);
+		this.triggerInterval = Math.max(1, triggerHandler.sampleNextValue());
+		if(removed)
+			SimulationManager.scheduleEvent(this);
+	}
+	
+	/**
+	 * Samples a new Value for the TriggerInterval
+	 */
+	public void resampleTriggerInterval(){
+		boolean removed = SimulationManager.removeEvent(this);
+		this.triggerInterval = Math.max(triggerIntervalStat.sampleNextValue(),1);
+		if(removed)
+			SimulationManager.scheduleEvent(this);
 	}
 
 	/**
@@ -286,4 +330,35 @@ public class Port {
 					return connection.getLink().getTransmissionDelayFrom(owner, to.getOwner());
 		return Long.MAX_VALUE;
 	}
+
+	@Override
+	public long getEventTime() {
+		return lastTrigger+triggerInterval+currentJitter;
+	}
+
+	@Override
+	public void simulateEvent(long time) {
+		if(connection==null || connection.getProtocol()==null || connection.getLink()==null || owner == null)
+			return;
+		
+		/**
+		 * Packets of the transfer initiated by this port
+		 */
+		Collection<Packet> packets = connection.getProtocol().generateNextPackets(this, time, false);
+		
+		//Packets encapsulated by Connection
+		packets = connection.encapsulatePackages(packets);
+		
+		//Encapsulate packets in Links
+		packets = connection.getLink().encapsulatePackages(packets);
+		
+		connection.getLink().addPackets(packets);
+		
+		//TODO: Sample next game
+		triggerInterval = Math.max(1,triggerIntervalStat.sampleNextValue());
+		
+		if(status==Port.SENDING && connection.getStatus()==Connection.ACTIVE)
+			SimulationManager.scheduleEvent(this);
+		
+	}
 }

+ 44 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/PrecisionLink.java

@@ -48,6 +48,9 @@ public class PrecisionLink implements Link {
 	 */
 	private boolean statusChanged;
 
+	/**
+	 * Delay between two devices, fixed
+	 */
 	private long fixedDelay=3;
 
 	/**
@@ -155,6 +158,11 @@ public class PrecisionLink implements Link {
 			last = packets.getLast();
 		}
 	}
+	
+	@Override
+	public Collection<Packet> encapsulatePackages(Collection<Packet> packets){
+		return packets;
+	}
 
 	@Override
 	public Collection<Packet> getPackets() {
@@ -201,4 +209,40 @@ public class PrecisionLink implements Link {
 	public long  getFixedDelay(){
 		return this.fixedDelay;
 	}
+
+	@Override
+	public void addPackets(Collection<Packet> packets) {
+		this.packets.addAll(packets);
+	}
+
+	@Override
+	public void initSimulationInterval(long startTime, long duration) {
+		/**
+		 * Reset packets
+		 */
+		packets.clear();
+		/**
+		 * Add out of Bounds packets
+		 */
+		packets.addAll(outOfBoundsPackets);
+	}
+
+	@Override
+	public void finalizeSimulationInterval(long startTime, long duration) {
+		//Remove out of Bounds Packets
+		/**
+		 * Remove packets which are not being sent in this time interval
+		 */
+		outOfBoundsPackets.clear();
+		/**
+		 * Last package, which should be sent in the next time step
+		 */
+		Packet last = packets.isEmpty()? null : packets.getLast();
+		while (last != null&&last.getTimestamp()>startTime+duration) {
+			outOfBoundsPackets.addFirst(packets.removeLast());
+			if(packets.isEmpty())
+				break;
+			last = packets.getLast();
+		}
+	}
 }

+ 39 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ProbabilityDistributionHandler.java

@@ -0,0 +1,39 @@
+package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
+
+import javax.swing.JPanel;
+
+import org.apache.commons.math3.random.RandomGenerator;
+
+/**
+ * Allows selection and configuration of such a class in view. Also Import & visualization of the example panel.
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public interface ProbabilityDistributionHandler {
+
+	/**
+	 * Set the random generator which should be used
+	 * @param rng random generator
+	 */
+	public void setRandomGenerator(RandomGenerator rng);
+
+	/**
+	 * Next value from the distribution
+	 * @return next sample value
+	 */
+	public long sampleNextValue();
+	
+	/**
+	 * Returns a configuration panel for the distribution.
+	 * Should be set enabled, visible and embedded by the calling methods.
+	 * @return panel for configuration
+	 */
+	public JPanel getConfigurationPanel();
+	
+	/**
+	 * Returns a simple description/name/identifier of the Distribution.
+	 * For example: "Gaussian Distribution"
+	 * @return simple description
+	 */
+	public String getSimpleDescription();
+}

+ 60 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SimulationManager.java

@@ -6,6 +6,8 @@ import java.util.Observable;
 import javax.swing.Timer;
 
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Scheduler;
 
 /**
  * Manages the Simulation by calling the relevant methods.
@@ -74,6 +76,11 @@ public class SimulationManager extends Observable {
 	 */
 	//private long perfStart = 0;
 	
+	/**
+	 * Scheduler which stores the event queue and enables scheduling and running of further events
+	 */
+	private static Scheduler scheduler;
+	
 	/**
 	 * Creates a new Simulationmanager
 	 * 
@@ -86,6 +93,7 @@ public class SimulationManager extends Observable {
 		this.collectionMan = new PacketCollectionManager(model);
 		this.exportMan = new PacketExportManager(model);
 		timer = new Timer(0, t -> simulateTimeStep());
+		scheduler = new Scheduler();
 	}
 
 	/**
@@ -118,8 +126,33 @@ public class SimulationManager extends Observable {
 	 *            Duration of the simulation interval in milliseconds
 	 */
 	public void simulateTimeIntervall(long startTime, long duration) {
+		scheduler.setMinTime(startTime);
+		//TODO: Fill Queue
+		//TODO: Simulate Schedule
+		//TODO: Export
+		
 		//Simulates the network
-		simulateNetwork(startTime, duration);
+		boolean oldWay = false;
+		if(oldWay)
+			simulateNetwork(startTime, duration);
+		else{
+			long maxTime = startTime + duration;
+			scheduler.scheduleAll(model);
+			for(Connection con:model.getConnections()){
+				Link l = con.getLink();
+				if(l!=null){
+					l.getPackets().clear();
+					l.addPackets(con.getTerminationPackages(startTime));
+				}
+			}
+			while(scheduler.hasNext(maxTime)){
+				Schedulable currentEvent = scheduler.getAndRemoveFirst();
+				//System.out.println("Event time: "+currentEvent.getEventTime());
+				currentEvent.simulateEvent(currentEvent.getEventTime());
+			}
+			// Simulate SmartDevices - if they need some logic -> TODO: Insert as schedulable
+			model.getDevices().forEach(d -> d.simulateTimeStep(startTime, duration));
+		}
 		runAlgorithms(startTime+duration);
 		collectionMan.collectPackets();
 		//Run all 
@@ -138,6 +171,7 @@ public class SimulationManager extends Observable {
 	 *            Duration of the simulation interval in milliseconds
 	 */
 	private void simulateNetwork(long startTime, long duration){
+		//TODO: Implement Event Schedule
 		// Nothing changed so far
 		statusChanged = false;
 		// Simulate all Links, and their connections
@@ -204,6 +238,12 @@ public class SimulationManager extends Observable {
 			for (Port p : d.getPorts())
 				if (p.getLastTrigger() > timestep)
 					p.setLastTrigger(timestep);
+		scheduler.reset(timestep);
+		/**
+		for(Connection c: model.getConnections())
+			for(Port p: c.getParticipants())
+				if (p.getLastTrigger() > timestep)
+					System.out.println("P without owner: "+p.toString());*/
 	}
 
 	/**
@@ -327,6 +367,7 @@ public class SimulationManager extends Observable {
 		this.controller = controller;
 		if(algo!=null)
 			algos.add(algo);
+		
 	}
 	
 	/**
@@ -352,4 +393,22 @@ public class SimulationManager extends Observable {
 	public PacketExportManager getPacketExportManager(){
 		return exportMan;
 	}
+	
+	/**
+	 * Adds an event to the event queue, which will be simulated later. Returns falls, if it could not be added (e.g. timestep to low)
+	 * @param event event which should be scheduled
+	 * @return true if it was scheduled, false if not
+	 */
+	public static boolean scheduleEvent(Schedulable event){
+		return scheduler.scheduleEvent(event);
+	}
+	
+	/**
+	 * Removes an event from the global event queue
+	 * @param event Event which should be removed
+	 * @return true, if it was removed, false if not
+	 */
+	public static boolean removeEvent(Schedulable event){
+		return scheduler.removeEvent(event);
+	}
 }

+ 21 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/SmartDevice.java

@@ -10,7 +10,12 @@ import java.util.List;
  * @author Andreas T. Meyer-Berg
  */
 public class SmartDevice {
-
+	
+	/**
+	 * Label
+	 */
+	protected short label = 0;
+	
 	/**
 	 * Name of the Device
 	 */
@@ -204,5 +209,20 @@ public class SmartDevice {
 	public void removePort(Port port) {
 		this.ports.remove(port);
 	}
+	
+	/**
+	 * @return label
+	 */
+	public short getLabel() {
+		return label;
+	}
+	
+	/**
+	 * Sets the label
+	 * @param label label to set
+	 */
+	public void setLabel(Short label) {
+		this.label = label;
+	}
 
 }

+ 39 - 0
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/configuration/ImportConfiguration.java

@@ -2,17 +2,23 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.configuration;
 
 import java.util.LinkedList;
 
+import org.apache.commons.math3.distribution.PoissonDistribution;
+
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Connection;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPerformance;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ConnectionPrecision;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Link;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PrecisionLink;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.ProbabilityDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.BoolSensorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatCollectorDevice;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices.FloatSensorDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.ConstantValueDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.NormalDistributionHandler;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.distributionHandler.PoissonDistributionHandler;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.MQTT_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.Ping_protocol;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.simpleImplementation.SimpleLink;
@@ -42,6 +48,8 @@ public class ImportConfiguration {
 	private LinkedList<Class<? extends SmartDevice>> standardSmartDevices = new LinkedList<Class<? extends SmartDevice>>();
 	private LinkedList<Class<? extends SmartDevice>> importedSmartDevices = new LinkedList<Class<? extends SmartDevice>>();
 	
+	private LinkedList<Class<? extends ProbabilityDistributionHandler>> standardDistributions = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
+	private LinkedList<Class<? extends ProbabilityDistributionHandler>> importedDistribution = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
 	/**
 	 * Initializes the configuration and adds the standard classes
 	 */
@@ -63,6 +71,10 @@ public class ImportConfiguration {
 		
 		standardConnections.add(ConnectionPerformance.class);
 		standardConnections.add(ConnectionPrecision.class);
+		
+		standardDistributions.add(ConstantValueDistributionHandler.class);
+		standardDistributions.add(NormalDistributionHandler.class);
+		standardDistributions.add(PoissonDistributionHandler.class);
 	}
 	
 	
@@ -174,4 +186,31 @@ public class ImportConfiguration {
 		importedSmartDevices.remove(remove);
 	}
 
+	
+	/**
+	 * Returns DistributionHandler Classes of the Model
+	 * @return available DistributionHandler Classes
+	 */
+	public LinkedList<Class<? extends ProbabilityDistributionHandler>> getDistributionHandlerClasses(){
+		LinkedList<Class<? extends ProbabilityDistributionHandler>> export = new LinkedList<Class<? extends ProbabilityDistributionHandler>>();
+		export.addAll(standardDistributions);
+		export.addAll(importedDistribution);
+		return export;
+	}
+	
+	/**
+	 * Adds new DistributionHandler Class to the available DistributionHandler classes
+	 * @param newDistributionHandler new DistributionHandler Class to be added
+	 */
+	public void addDistributionHandlerClass(Class<? extends ProbabilityDistributionHandler> newDistributionHandler){
+		importedDistribution.add(newDistributionHandler);
+	}
+	
+	/**
+	 * Removes DistributionHandler Class from the available DistributionHandler Classes
+	 * @param remove DistributionHandler Class to be removed
+	 */
+	public void removeDistributionHandlerClass(Class<? extends ProbabilityDistributionHandler> remove){
+		importedDistribution.remove(remove);
+	}
 }

+ 25 - 1
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/devices/FloatSensorDevice.java

@@ -2,7 +2,9 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.devices;
 
 import java.util.Random;
 
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SimulationManager;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.scheduler.Schedulable;
 
 
 /**
@@ -10,7 +12,7 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
  *
  * @author Andreas T. Meyer-Berg
  */
-public class FloatSensorDevice extends SmartDevice implements FloatSensor {
+public class FloatSensorDevice extends SmartDevice implements FloatSensor, Schedulable {
 
 	/**
 	 * Minimum value
@@ -29,6 +31,11 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {
 	 */
 	private float oldVal;
 	
+	/**
+	 * Timestep it will be udpated again
+	 */
+	long nextSimulationTime = 0;
+	
 	/**
 	 * Name of the sensor reading
 	 */
@@ -56,6 +63,7 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {
 		val = 22;
 		oldVal = 22;
 		infoName = "temperature";
+		SimulationManager.scheduleEvent(this);
 	}
 	
 	@Override
@@ -101,6 +109,22 @@ public class FloatSensorDevice extends SmartDevice implements FloatSensor {