Skip to content
Snippets Groups Projects
Antifurto.java 8.89 KiB
Newer Older
  • Learn to ignore specific revisions
  • Elisa Giglio's avatar
    Elisa Giglio committed
    package code;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Date;
    
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.MqttTopic;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    public class Antifurto {
    
    	private static String brokerUrl;
    	private String interruttore;
    	private String interruttoreOutputSuono;
    
    	private String nomeOutputAntifurto;
    	private static JSONArray sensori;  // sensori di movimento
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static ArrayList<String> topicsSub;
    	private Date date = new Date();
    	private String clientId = Long.toString(date.getTime()) + "-sub-pub"; // unique client id
    	private Automa automa;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private MqttClient mqttClient;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static String mqttDomain;
    	private static String mqttSubdomain;
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private final String CONF_FILE = "../res/CONF/conf.json";
    
    	public static final String CONF_ZONA = "../res/CONF/zona.json";
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public Antifurto(Automa automa) throws JSONException, IOException, MqttException {
    		this.automa = automa;
    
    		JSONObject jsonObject = new JSONObject(Helper.leggiFile(CONF_FILE));
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		brokerUrl = jsonObject.getString("protocol") + "://" + jsonObject.getString("broker") + ":" + jsonObject.getInt("port");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		mqttDomain = jsonObject.getString("mqttDomain");
    		mqttSubdomain = jsonObject.getString("mqttSubdomain");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		topicsSub = new ArrayList<String>();
    
    
    		// Su questo topic ricevero' un messaggio del tipo {request:description}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		// Dovro' quindi mandare la mia descrizione json
    
    		topicsSub.add("to/all");
    
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		// Su questo topic ricevero' le richieste di inviare il mio stato attuale
    
    		topicsSub.add("rpc/"+getMqttTree()+"/antifurto");
    
    		jsonObject = new JSONObject(Helper.leggiFile(CONF_ZONA));
    
    		interruttore = jsonObject.getString("interruttore");
    
    
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttore); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
    
    
    		// Per ogni sensore di movimento, sottoscrivo i messaggi che notificano il loro cambiamento di stato
    
    		sensori = jsonObject.getJSONArray("sensoriMovimento");
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		for(int i=0; i<sensori.length(); i++) {
    
    			topicsSub.add("from/"+getMqttTree()+"/gpio/" + sensori.get(i));
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		}
    
    		nomeOutputAntifurto = jsonObject.getString("nomeOutputAntifurto");
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + nomeOutputAntifurto);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		interruttoreOutputSuono = jsonObject.getString("outputSuono");
    
    		topicsSub.add("from/"+getMqttTree()+"/gpio/" + interruttoreOutputSuono); // Sottoscrivo i messaggi che notificano il cambiamento di stato dell'interruttore
    
    		topicsSub.add("to/"+getMqttTree()+"/antifurto/soglia"); // Su questo topic mi arrivera' un messaggio {"soglia": 30} e dovrò impostare la soglia di conseguenza
    
    
    		topicsSub.add("conf/"+getMqttTree()+"/antifurto/sensore"); // Su questo topic mi arrivera' un messaggio per l'aggiunta di un sensore di movimento.
    																   // Ad esempio se mi arriva il messaggio {"in": "IN3", "delta":33 } devo aggiungere il sensore di movimento che si
    
    																   // chiama IN3, il cui valore di delta e' 33 (devo quindi aggiornare il file deltaSensoriMovimento.json
    
    		topicsSub.add("to/"+getMqttTree()+"/antifurto/luceAntifurto");
    
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		this.mqttClient = new MqttClient(brokerUrl, clientId, new MemoryPersistence());
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public void startClient(Esecutore esec, Publisher publisher) throws MqttException {
    		MqttConnectOptions options = new MqttConnectOptions();
    		options.setCleanSession(false);
    
    		mqttClient.setCallback(new SubscribeCallback(this, publisher, interruttore, interruttoreOutputSuono, esec, automa, nomeOutputAntifurto));
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		mqttClient.connect(options);
    
    
    
    		for(String t: topicsSub)
    
    			addTopicToSubscribe(t);
    	}
    
    	// sottoscrive il topic passato come parametro
    	public void addTopicToSubscribe(String topic) throws MqttException {
    		mqttClient.subscribe(topic);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public void publishMethod(String topic, String msg) throws MqttException {
    		final MqttTopic msgTopic = mqttClient.getTopic(topic);
    		msgTopic.publish(new MqttMessage(msg.getBytes()));
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	/*
    	 * Abbiamo 3 tipi di eventi:
    
    	 * 		to 		Command Events - mi viene richiesto di eseguire un comando --> sottoscrivo
    	 * 		from 	Status Events - io annuncio un cambiamento di stato
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 								(inviato a tutti i client che hanno sottoscritto il topic su cui faccio la publish)
    
    	 * 		rpc 	Query Events - richiesta di inviare uno stato a un client (o microservizio). --> sottoscrivo
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 			  				   Query implementati come coppia di eventi: <query event, status event>
    	 * RICORDIAMO COME ABBIAMO IMPLEMENTATO LA RPC SU MQTT
    
    	 *
    	 *
    	 *
    	 * Il cuore della nostra business logic è un metodo in cui mi metto in attesa su mqtt e:
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 		se arriva un comando, chiamo il metodo responsabile per eseguire quel comando;
    	 * 		se arriva un evento di stato, chiamo il metodo responsabile per gestire quell'evento di stato;
    
    	 * 		se arriva una remote procedure call, attivo la risposta sulla remote procedure call
    	 *
    	 *
    	 *
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * Capire come gestire sistema a regole (vedi slide "Esempio" in "Applicazioni IoT "Cloud Based"")
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * Sicurezza gestita con TLS
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * FILE DA FARE per un servizio: (?)
    
    	 * 		file che contiene le informazioni per connettersi al mosquitto locale
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 		file che dice qual'è la porta che lui deve esporre
    	 * 		file che mi dice tutte le cose che lo configurano, ad esempio quanti device deve guardare
    	 * 		...
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 	I file di configurazione sono in JSON o in XML
    	 * I dati persistiti si troveranno nella sottodirectory (chiamata con il nome del servizio) di Home
    
    	 *
    	 *
    	 * Nella fase di configurazione potremo ancora modificare i file di configurazione (ad esempio aggiungendo device,
    	 * regole). Dopodiché quando si fa partire il servizio si inizierà a usare l'altra parte di file system (ovvero il Local
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * Dynamic File System) dove si andranno a salvare gli stati per renderli persistenti.
    
    	 *
    	 *
    	 *
    	 * Ho un processo principale che come unico compito ha quello di fare una fork() e creare un processo figlio.
    	 * Sarà questo processo figlio a eseguire effettivamente il programma. Se il processo figlio termina (PER UN QUALCHE
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * PROBLEMA), allora il processo padre se ne accorge e fa ripartire un nuovo processo figlio.
    
    	 *
    	 *
    	 * Devo avere una thread di configurazione che obbedisce ai miei comandi (dati sulla HAT interface andando su
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * 	192.168.0.101:9001/configure.html (dove 192.168.0.101 è l'indirizzo della beaglebone)
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * Ho una classe che implementa l'automa a stati finiti
    
    	 *
    	 *
    	 *
    	 *
    	 * DA FARE:
    	 * All'avvio, leggo il file stato e mi imposto di conseguenza. Poi interrogo la beaglebone per sapere SOLO lo stato
    	 * dell'antifurto (luce rossa), ovvero se l'antifurto e' on o off. Lo stato del sensore di suono, non mi interessa: poiche'
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * sono solo io a impostarlo (la web app si comporta in conseguenza dei miei messaggi).
    
    	 * Mi serve interrogare la beaglebone per lo stato dell'antifurto perche' puo' succedere che l'antifurto abbia avuto
    	 * dei problemi e quindi non abbia funzionato per un po' e nel mentre l'utente ha attivato l'antifurto dagli scenari.
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * Quindi proprio perche' sia il mio antifurto sia gli scenari comandano lo stesso antifurto, devo fare questa richiesta
    	 * alla beaglebone.
    
    	 * Dopo aver chiesto lo stato dell'antifurto alla beaglebone, so esattamente lo stato in cui devo essere --> mi imposto
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	 * di conseguenza!
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	*/
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public static void main(String args[]) throws JSONException, IOException, MqttException {
    		//PER TESTARE PRIMA TOGLI IL TRY CATCH !!!!! POI QUANDO TUTTO FUNZIONA, METTI IL TRY CATCH, togli le throws E IMPLEMENTA LA RIPARTENZA!
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    //		while(true) {
    //			try {
    				startSystem();
    //			}
    //			catch(Exception e) {
    //				// DA FARE:
    
    //				// qui metto il codice per far ripartire il processo: rileggo lo stato dei sensori e dell'interruttore,
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    //				// capisco di conseguenza in quale stato dell'automa mi trovo e riparto.
    //				startSystem();
    //			}
    //		}
    	}
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	private static void startSystem() throws JSONException, IOException, MqttException {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		MyQueue<Integer> codaVal = new MyQueue<Integer>();
    		MyQueue<Pair> codaMsg = new MyQueue<Pair>();
    		Automa automa = new Automa();
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		Antifurto antifurto = new Antifurto(automa);
    		Publisher publisher = new Publisher(codaMsg, antifurto);
    		Esecutore esec = new Esecutore(publisher, codaVal, automa, antifurto.interruttoreOutputSuono);
    
    		Timer timer = new Timer(6000,-1,esec,automa);
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    		antifurto.startClient(esec, publisher);
    		publisher.start();
    		esec.start();
    		timer.start();
    	}
    
    
    	public static void stopSystem() {
    
    Elisa Giglio's avatar
    Elisa Giglio committed
    	public static String getMqttTree() {
    		return mqttDomain+"/"+mqttSubdomain;
    	}
    
    
    	public static JSONArray getSensori() {
    		return sensori;
    	}
    
    	public static void addSensore(String newSensore) { // aggiunge un sensore di movimento
    		sensori.put(newSensore);
    	}