package code; import java.io.IOException; import java.util.Date; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.json.JSONException; import org.json.JSONObject; public class SubscribeCallback implements MqttCallback{ private Antifurto client; private Publisher publisher; private String nomeInterruttore; private String nomeOutputSuono; private String nomeOutputAntifurto; private Esecutore esec; private Automa automa; public SubscribeCallback(Antifurto client, Publisher publisher, String nomeInterruttore, String nomeOutputSuono, Esecutore esec, Automa automa, String nomeOutputAntifurto) { this.client = client; this.publisher = publisher; this.nomeInterruttore = nomeInterruttore; this.nomeOutputSuono = nomeOutputSuono; this.nomeOutputAntifurto = nomeOutputAntifurto; this.esec = esec; this.automa = automa; } @Override public void connectionLost(Throwable arg0) { boolean retry = true; final Date d = new Date(); Date d2 = new Date(); long time = Math.abs(d2.getTime()-d.getTime()); while(retry & (time<600000)) { try { client.startClient(esec, publisher); retry = false; } catch (MqttException e) { d2 = new Date(); time = Math.abs(d2.getTime()-d.getTime()); } } if(time>=600000) { System.out.println("Tentativo di riconnessione fallito"); System.exit(1); } } @Override public void deliveryComplete(IMqttDeliveryToken arg0) { // Nessuna operazione } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { if(topic.equals("to/all")) { System.out.println("MESSAGGIO MQTT = "+message.toString()); if(message.toString().equals("{request:description}")) sendDescription("from/"+Antifurto.getMqttTree()+"/antifurto/description"); if(message.toString().equals("{request:status}")) sendMyStateToAll("from/"+Antifurto.getMqttTree()+"/antifurto"); // DA FARE: vedi cosa pubblicano gli altri microservizi e implementa di conseguenza questa funzione } else { JSONObject msgJson = new JSONObject(message.toString()); if(topic.equals("conf/"+Antifurto.getMqttTree()+"/antifurto/sensore")) { if(msgJson.has("in") && msgJson.has("delta")) handleConfSensoreMovimento(msgJson); } else { if(topic.equals("to/"+Antifurto.getMqttTree()+"/antifurto/soglia") && msgJson.has("soglia")) { handleSetSoglia(msgJson); } else { if(topic.equals("rpc/"+Antifurto.getMqttTree()+"/antifurto") && message.toString().equals("{\"request\":\"description\"}")) sendMyState("from/"+Antifurto.getMqttTree()+"/antifurto"); else { if(topic.equals("from/"+Antifurto.getMqttTree()+"/gpio/"+nomeOutputSuono)) { int newStatus = -1; if(msgJson.has("status")) newStatus = msgJson.getInt("status"); else { if(msgJson.has("event")) newStatus = msgJson.getInt("event"); } handleStateMsgFromOutputSuono(newStatus); } else { if(topic.equals("from/"+Antifurto.getMqttTree()+"/gpio/"+nomeOutputAntifurto)) { if(msgJson.has("event")) handleLuceAntifurto(); } else { int event = msgJson.getInt("event"); if(event==1) { // e' stato premuto l'interruttore / il sensore di movimento ha rilevato qualcuno if(topic.equals("from/"+Antifurto.getMqttTree()+"/gpio/"+nomeInterruttore)) handleStateMsgFromInterruttore(); else { // il topic sara' from/gruppo2/luci/gpio/IN0 dove IN0 e' un sensore di movimento System.out.println("TOPIC = "+topic); String[] t = topic.split("/"); handleMovimento(t[4]); } } } } } } } } } private synchronized void handleStateMsgFromInterruttore() throws JSONException, IOException { if(automa.getStatoInterruttore().equals("on")) publisher.aggiungiComando("to/"+Antifurto.getMqttTree()+"/gpio/"+nomeOutputAntifurto, "{cmd:0}"); // voglio spegnere l'antifurto, quindi invio un messaggio per spegnere la luce che indica che l'antifurto e' acceso else publisher.aggiungiComando("to/"+Antifurto.getMqttTree()+"/gpio/"+nomeOutputAntifurto, "{cmd:1}"); // voglio accendere l'antifurto, quindi invio un messaggio per accendere la luce che indica che l'antifurto e' acceso } private synchronized void handleLuceAntifurto() throws JSONException { try { automa.changeStatoInterruttore(); if(automa.getStatoInterruttore().equals("off")) { publisher.aggiungiComando("to/"+Antifurto.getMqttTree()+"/gpio/"+nomeOutputSuono, "{cmd:0}"); esec.reset(); } JSONObject js = new JSONObject(); js.put("event", automa.getStatoInterrutoreTrueFalse()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/antifurto", js.toString()); } catch(IOException e) { JSONObject jsError = new JSONObject(); jsError.put("error", e.getMessage()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/antifurto", jsError.toString()); } } private synchronized void handleStateMsgFromOutputSuono(int newStatus) throws JSONException, IOException { if(newStatus!=-1) { String statusOnOff = automa.converter(newStatus); // lo stato e' della forma "on" oppure "off" if(! statusOnOff.equals(automa.getStatoSuono()) ) { automa.aggiornaStatoSuono(statusOnOff); JSONObject js = new JSONObject(); js.put("event", automa.getStatoSuonoTrueFalse()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/allarme", js.toString()); } } } private void handleMovimento(String nomeSensore) { if(automa.getStatoInterruttore().equals("on")) esec.aggiungiVal(automa.getDelta(nomeSensore)); } private void handleConfSensoreMovimento(JSONObject toAdd) throws JSONException { // aggiorno il file che contiene l'associazione sensore-movimento, delta try { JSONObject sensori = new JSONObject(Helper.leggiFile(Automa.FILE_DELTA_SENSORI)); String nomeSensore = toAdd.getString("in").toUpperCase(); int delta = toAdd.getInt("delta"); sensori.put(nomeSensore, delta); Helper.scriviFile(sensori, Automa.FILE_DELTA_SENSORI); // aggiorno il file zona: ho un sensore di movimento in piĆ¹ JSONObject zona = new JSONObject(Helper.leggiFile(Antifurto.CONF_ZONA)); zona.getJSONArray("sensoriMovimento").put(nomeSensore); Helper.scriviFile(zona, Antifurto.CONF_ZONA); Antifurto.addSensore(nomeSensore); automa.addDeltaSensori(nomeSensore, delta); client.addTopicToSubscribe("from/"+Antifurto.getMqttTree()+"/gpio/"+nomeSensore); System.out.println("from/"+Antifurto.getMqttTree()+"/gpio/"+nomeSensore); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/sensore", toAdd.toString()); // invio questo messaggio per confermare alla web app che il sensore di movimento e' stato aggiunto } catch(IOException | MqttException e) { JSONObject jsError = new JSONObject(); jsError.put("error", e.getMessage()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/sensore", jsError.toString()); } } private void handleSetSoglia(JSONObject jsSoglia) throws JSONException { try { Esecutore.setSoglia(jsSoglia.getInt("soglia")); JSONObject jsToSend = new JSONObject(); jsToSend.put("soglia", Esecutore.getSoglia()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/soglia", jsToSend.toString()); } catch(IOException e) { JSONObject jsError = new JSONObject(); jsError.put("error", e.getMessage()); publisher.aggiungiComando("from/"+Antifurto.getMqttTree()+"/antifurto/soglia", jsError.toString()); } } private void sendMyState(String topic) throws MqttException, NumberFormatException, JSONException { JSONObject json = new JSONObject(); json.put("stato", automa.getStatoAutoma()); json.put("interruttore", nomeInterruttore); json.put("sensori-movimento", Antifurto.getSensori()); json.put("output-suono", nomeOutputSuono); json.put("soglia", Esecutore.getSoglia()); json.put("allarme", automa.getStatoSuonoTrueFalse()); json.put("valore-attuale", esec.getValore()); json.put("antifurto", automa.getStatoInterrutoreTrueFalse()); long allarmeTimeout = Esecutore.getAllarmeTimeout(); if(automa.getStatoAutoma() == 2 && allarmeTimeout > 0) json.put("allarme-timeout", allarmeTimeout); publisher.aggiungiComando(topic, json.toString()); } private void sendDescription(String topic) { // DA FARE: guardare quale descrizione manda netmon, archiver, meter,... e confrontare l'implementazione di questo metodo String key = topic.replaceFirst("/description", ""); String msg = "{\""+key+"\":[\"statoAntifurto\":\"" + automa.getStatoInterruttore()+"]"+"}"; // // //DA FARE quali IN uso, quali Out uso, statoSuono, valore, soglia, statoInterruttore // [{"statoAntifurto":"on"}, // {"allarme":"on"}, // {"valore":5}, // {"soglia":1000}, // {"interruttore":"IN0"}, // {"sensoreDiMovimento":"IN1"}, // {"sensoreDiMovimento":"IN2"}, // {"sensoreDiMovimento":"IN3"}, // {"sensoreSuono":"OUT3"},] // publisher.aggiungiComando(topic, msg); } private void sendMyStateToAll(String topic) { // DA FARE } }