Erste Schritte Dynamisch Objekte erzeugen und diese durchsuchen

DennisSA

Mitglied
Hallo Java-User,
ich bin gerade an einem Problem dran, bei dem ich nicht weiter komme.

Folgende Situation:
Ich schreibe eine App in Android (Eclipse) für ein Laborprojekt meiner Hochschule. Innerhalb dieser App wird via Bluetooth nach "Sensoren" gesucht, ohne mich vorher mit ihnen koppeln zu müssen. Diese Sensoren senden ihre MAC-Adresse mit, sowie den jeweiligen Messwert (Temperatur bspw.). Dieser Messwert wird dann dargestellt auf dem Smartphone und das ganze wiederholt sich alle 500 Millisekunden. Soviel zum Szenario. Jeder Sensor liefert also alle 500ms einen neuen Messwert aus.

Bisher habe ich 2 Sensoren benutzt, deren MAC-Adresse mir bekannt waren und konnte so abfragen ob der Messwert jetzt zu Sensor1 oder Sensor2 gehört. Mein Prof hätte nun gern, dass das ganze dynamisch läuft, heißt: Wenn 10 Sensoren da sind, sollen 10 angezeigt werden. Da aber jeder alle 500ms neue Messwerte sendet, muss ich den jeweiligen Messwert anhand der MAC-Adresse dem jeweiligen Sensor zuordnen. Als Obergrenze werden 256 unterschiedliche Sensoren (und damit auch MAC-Adressen) festgelegt.

Ich brauche also ein Konstrukt, welches abhängig von der Anzahl der Sensoren unterschiedlich viele Anzeigen auf dem Display realisiert und diese dann jeweils "updated" sobald ein bereits bekannter Sensor einen neuen Messwert sendet. Wenn ein Sensor außerhalb der Bluetooth-Reichweite ist, dann soll der Messwert auf dem Display auch wieder verschwinden/gelöscht werden.

Leider habe ich keine Ahnung in welche Richtung ich dort gehen muss. Vielleicht habt ihr mir einen Tipp oder einen Ansatz.

Jeder Sensor hat eine MAC-Adresse und einen Messwert. Ich dachte da schon an ein "Struct" (was in Java ja nicht existiert, jedoch über eine Klasse realisiert werden kann), jedoch scheitere ich im Ansatz.

MAC-Adresse bekomme ich vom Scan als "String" und der Messwert ist ein byte[] Array

EDIT: Als Ablauf:
1. Scannen
2. Überprüfung: if(neuer Sensor?) --> Variable mit MAC-Adresse und Messwert anlegen
else(bereits bekannter Sensor --> Messwert updaten)
 
Zuletzt bearbeitet:
Das ist nicht zeitabhängig. Wenn der Scan-Prozess diesen Sensor nicht mehr findet, dann ist er außer Reichweite.

Ich geb mal ein Beispiel:
Scan-Prozess1 liefert Sensor1, Sensor 3, Sensor4, Sensor5

Scan-Prozess2 liefert Sensor1, Sensor 2, Sensor4, Sensor5

Das heißt Sensor3 wird nicht mehr gefunden (die MAC-Adresse von Sensor3), also soll Sensor3 nicht weiter angezeigt werden. Dafür kam Sensor2 neu dazu.
 
Die Frage ist jetzt, wie du deine Daten darstellen kannst? Oder wie du am besten herausfindest, welche Sensoren schon vorhanden sind und updatest?
 
Die Daten werden in einer Art Diagramm dargestellt. Die Diagrammfunktion benötigt nur den Messwert und den Sensornamen und macht den Rest (wurde nicht von mir entwickelt).
 
Also ich würde mir soetwas wie einen SensorManager basteln, der mir alle aktuellen Sensoren (die Verbunden sind) hält. Unter verbunden, verstehe ich die < 500 ms alte Temperatur geliefert haben.

Jedes mal, wenn ein Sensor zum Senden beginnt, würde ich einen Timer starten, der nach ~600 ms den Sensor aus dem Manager löscht und die GUI updated.
Wenn die Nachrichten regelmäßig ankommen, dann wird der Timer jedes mal zurückgesetzt (also ein klassischer time out).

Also ich hab mal was gebastelt:

Java:
public interface MeasurementListener {
	void receive(String macId, int temperature);
}

Java:
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

public class SensorManager implements MeasurementListener {
	private Map<String, Integer> sensors;
	private Map<String, Timer> timers;
	private int updates = 0;
	
	public SensorManager() {
		sensors = new ConcurrentHashMap<>();
		timers = new ConcurrentHashMap<>();
	}
	
	public synchronized void display(String s) {
		System.out.println("----------------- UPDATE " + updates++ + "-----------------------");
		System.out.println("----------------- " + s + " ------------------------");
		for (Entry<String, Integer> sensor : sensors.entrySet()) {
			System.out.println(sensor.getKey() + ": " + sensor.getValue());
		}
	}
	
	@Override
	public void receive(String macId, int temperature) {
		if (sensors.containsKey(macId)) {
			timers.remove(macId).cancel();
		}
		sensors.put(macId, temperature);
		Timer t = new Timer();
		timers.put(macId, t);
		t.schedule(new TimerTask() {
			@Override
			public void run() {
				sensors.remove(macId);
				timers.remove(macId);
				display("Removed");
			}
		}, 600);
		
		display("Added");
	}
}

Java:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SensorTest {
	
	public static void main(String... args) {
		int numSensors = (int) (Math.random() * 5) + 2;
		TemperatureSensor[] sensors = new TemperatureSensor[numSensors];
		SensorManager manager = new SensorManager();
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < numSensors; i++) {
			TemperatureSensor sensor = new TemperatureSensor("Sensor" + i, manager);
			exec.execute(sensor);
			sensors[i] = sensor;
		}
		try {
			TimeUnit.SECONDS.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		for (TemperatureSensor sensor : sensors) {
			sensor.stop();
		}
		exec.shutdown();
	}
}

Java:
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class TemperatureSensor implements Runnable {
	private final String id;
	private boolean isRunning;
	private final MeasurementListener listener;
	
	public TemperatureSensor(String id, MeasurementListener listener) {
		this.id = id;
		this.listener = listener;
		this.isRunning = true;
	}
	
	public String getId() {
		return id;
	}
	
	public void stop() {
		isRunning = false;
	}
	
	@Override
	public void run() {
		Random rand = new Random();
		while (isRunning) {
			listener.receive(getId(), rand.nextInt(30));
			try {
				TimeUnit.MILLISECONDS.sleep(rand.nextBoolean() ? 500 : 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
 
Danke für deine Mühe. Teile aus dem Code hab ich jetz mal übernommen und bin meinem Ziel ein wenig näher gerückt.

Mich würde nur noch interessieren wie ich (mit einer Schleife oder so) die Datensätze nach einem bestimmten Sensor durchsuchen kann. Wenn die Suche bspw. Sensor41 nicht findet, dann soll dieser angelegt werden.
 
Naja wenn du das mit einer Map löst, so wie ich, dann frag doch, ob der Key enthalten ist mit containsKey?
 

Zurück
Oben