uOttaHack is Ottawa’s largest hackathon that takes place every year at University of Ottawa. This year’s theme involved solving issues related to the pandemic. Over 300 students from a variety of backgrounds registered! As a prime sponsor of the uOttaHack4 event, Solace challenged students to leverage the PubSub+ Event Broker: Cloud technology to create something truly unique.
A group of students from the Academy of Technology in India developed an ambulance tracking application called “Ambuplus”, which allows a quicker ambulance response. The project won the Solace “best use of PubSub+” prize and also 1st place overall.
Where We Got the Idea
Before the uOttaHack4 hackathon, one of our friends was in an urgent need of medical attention due to suffocation. We all were together, hanging out at his place when this situation occurred. Panic-struck, we hurried to dial the ambulance helpline, but unfortunately, they said it would take them around 30 minutes to come. But the weird thing is that we remember vividly that we saw an ambulance somewhere in the neighborhood when visiting that friend’s place. Left with no other option, we booked an Uber which thankfully drove him to the nearest hospital within 10 minutes.
Why did an Uber come faster than an ambulance? Aren’t there ambulances all around us? It was then that it hit us — the core idea of Ambuplus.
These days, emergency response time for ambulances has hiked to a whopping 150% with COVID-19 positive patients asked to stay home for more than 2-3 days. Patients dealing with real emergencies often get their ambulances late. Every second matters, and we can’t afford to lose a life because of delayed emergency response time. We need to change this!
Ambuplus is a real-time ambulance tracking application which brings the nearest rescue squad to the home of a sick person, ASAP! Apart from being the Uber for ambulances, it also requests blood from the closest blood banks and other users who use this app as well.
You can watch the video of our project in action and see our code in GitHub.
How We Developed It
Ambuplus is built on Android Native. We used Solace PubSub+ Event Broker for the live tracking of the ambulances and for initiating the blood requests from the user end. We also used Google Maps API to populate the information on the map viewport. The authentication of our app is done via Firebase Authentication. And last but not least, the chat server was deployed on a free dyno of Heroku. Our app is available in most local languages like Hindi, Bengali, Chinese, Korean, etc.
In the development of the application, we used Solace PubSub+ extensively in order to track ambulances in real time. Ambulances push their live locations to specific topics which the backend subscribes to. The backend calculates the nearest ambulance and matches it to the person in need of an ambulance. After this, the person’s application subscribes to the topic this ambulance is publishing its real time location to. We also confirm if beds are available at the hospital the ambulance goes to. Lastly, it’s supported by all devices above Android Lollipop!
Configuring the Solace broker connection details
We created a new Java file named “MessagingOptions” that will contain the Solace broker connection details that the app will use to connect to the Solace PubSub+ Event Broker.
public class MessagingOptions { /** * Configuring Solace Broker Connection Details * You'll receive these parameters from the Solace Dashboard itself */ public final String SOLACE_CLIENT_USER_NAME = "<SOLACE-USERNAME> "; public final String SOLACE_CLIENT_PASSWORD = "<SOLACE-PASSWORD>"; public final String SOLACE_MQTT_HOST = "<SOLACE-HOST>"; // Session parameters int SOLACE_CONNECTION_TIMEOUT = 3; int SOLACE_CONNECTION_KEEP_ALIVE_INTERVAL = 60; boolean SOLACE_CONNECTION_CLEAN_SESSION = true; boolean SOLACE_CONNECTION_RECONNECT = true; }
Creating the MQTT client helper class
We created another new Java file called “MqttClientHelper”. That file contains the connect
, subscribe
, and publish
methods. The connect
method established the connection with Solace PubSub+ Event Broker.
public void connect(){ MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setAutomaticReconnect(SOLACE_CONNECTION_RECONNECT); mqttConnectOptions.setCleanSession(SOLACE_CONNECTION_CLEAN_SESSION); mqttConnectOptions.setUserName(SOLACE_CLIENT_USER_NAME); mqttConnectOptions.setPassword(SOLACE_CLIENT_PASSWORD.toCharArray()); mqttConnectOptions.setConnectionTimeout(SOLACE_CONNECTION_TIMEOUT); mqttConnectOptions.setKeepAliveInterval(SOLACE_CONNECTION_KEEP_ALIVE_INTERVAL); try { mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions(); disconnectedBufferOptions.setBufferEnabled(true); disconnectedBufferOptions.setBufferSize(100); disconnectedBufferOptions.setPersistBuffer(false); disconnectedBufferOptions.setDeleteOldestMessages(false); mqttAndroidClient.setBufferOpts(disconnectedBufferOptions); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.d(TAG,"Failed to connect to server",exception); } }); } catch (MqttException e) { e.printStackTrace(); } }
The subscribe
method takes the two input parameters “topic name” and “quality of service” which are used to subscribe topics to Solace PubSub+ Event Broker and return a corresponding token.
public void subscribe(String topic, int qos){ try { mqttAndroidClient.subscribe(topic, qos, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Log.w(TAG, "Subscribed to topic "+topic); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.w(TAG, "Subscription to topic "+topic+" failed!"); } }); } catch (MqttException e) { System.err.println("Exception whilst subscribing to topic "+topic); e.printStackTrace(); } }
The publish
method takes the three input parameters “topic name”, “message”, and “quality of service” which are used to publicize the message as a payload to corresponding topics with quality of service provided.
public void publish(String topic, NotificationData msg, int qos){ MqttMessage mqttMessage = new MqttMessage(); String str = msg.getUserProfile()+"##"+msg.getNotificationType()+"##"+msg.getNotificationText()+"##"+msg.getNotificationTime(); mqttMessage.setPayload(str.getBytes()); try { mqttAndroidClient.publish(topic, mqttMessage.getPayload(), qos, false); Log.d(TAG, "Message published to topic "+topic+msg); } catch (MqttException e) { Log.d(TAG, "Error Publishing to $topic: " + e.getMessage()); e.printStackTrace(); } }
Subscribing to topics
We are subscribing to two topics named “ambulance” and “Blood”. The topic “ambulance” gets live tracking locations of the ambulances near the person in need of an ambulance. The topic “Blood” gets notifications for blood requirement.
mqttClientHelper = new MqttClientHelper(getActivity().getApplicationContext()); requestContactPermission(root); setMqttCallBack(); mqttClientHelper.subscribe("Blood",0); mqttClientHelper.subscribe("ambulance",0);
Publishing to topics
We are publishing live locations of ambulances near the person who needs an ambulance to the “ambulance” topic through Solace PubSub+ Event Broker.
Calendar e = Calendar.getInstance(); Date date = e.getTime(); NotificationData notificationData = new NotificationData(user.getUid(),"Ambulance Location",""+lat+"##"+lng,date.toString(),user.getUid()); mqttClientHelper.publish("ambulance",notificationData,0);
We are publishing blood groups as a cloud messaging service to the “Blood” topic through Solace PubSub+ Event Broker.
String title = "Location : https://maps.google.com/maps?daddr="+lat+","+lng+"\nPhone : "+phone+"\nHi, I am "+name+" and I need urgent "+blood+" blood"; String notificationIconUrl = "https://firebasestorage.googleapis.com/v0/b/wosafe-5e1fc.appspot.com/o/notification_icon%2Fnotification_icon.png?alt=media&token=4b204bf6-9485-420b-b4c6-58a060d635a0"; NotificationData notificationData = new NotificationData(userPic,notificationIconUrl,title,date.toString(),firebaseAuth.getUid()); mqttClientHelper.publish("Blood",notificationData,0);
On MessageArrived
The messageArrived
method will return the topic name and message from Solace PubSub+ Event Broker.
@Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.w("Debug","Message received from host "+message); String[] str = message.toString().split("##"); if(str.length == 4) { NotificationData notificationData = new NotificationData(str[0], str[1], str[2], str[3], firebaseAuth.getUid()); db.collection("Notification") .add(notificationData) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { documentId = documentReference.getId(); Log.d(TAG, documentReference.getId()); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); } }); } else { latLng2 = new LatLng(Double.parseDouble(str[2]),Double.parseDouble(str[3])); mMap.addMarker(new MarkerOptions().position(latLng2).icon(BitmapDescriptorFactory.fromResource(R.drawable.flash_icon)));}}
What We Learned
Establishing connection routes between different devices might seem easy but isn’t, but we are truly grateful to Solace PubSub+ as it helped us cut the hassle to a great extent, hence reducing our development time which is a matter of great concern during hackathons!
We feel proud to say that this was the first time we integrated Solace PubSub+ in our project, but we learned so many new things regarding MQTT operations. Moreover, it was quite exciting to create new custom components for the Android application, set up the Google Maps API, and configure Firebase in such a short time! We also enhanced our Stack Overflow searching skill during the hackathon.
What’s Next
We really want this project to have a positive impact on people’s lives! Specifically, we would love to make it more scalable and become a cross-platform application so that the user interaction increases to a great extent.
Authors