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

Pratyay Banerjee is an Electronics & Communication Engineering Junior at the Academy of Technology. He’s a FOSS enthusiast who likes to intersect Web and ML by building novel solutions to challenging real-world problems.

Saif Ali is a third year Electronics & Communication Engineering Student at the Academy of Technology. He is passionate about cloud and mobile development and loves to develop solutions to real-world issues.

Sandipan Dey is a third year Computer Science Engineering student from Academy of Technology. He loves working with new technologies but creating scalable backends is what he specializes in.

Debdut Goswami is a Junior from the Academy of Technology in Computer Science Engineering. His interests lie in backend development, deployment, and integrations.

 

Logo Solace Community Solly
Solace Community

The Solace Developer Community is the technical community for Solace PubSub+. It is the place where community members from all backgrounds and experiences socialize, share resources, organize projects together, and help each other. If you haven't already signed up for it, we encourage you to do so now and get involved in the action!

Join Our Developer Community

Join the Solace Developer Community to discuss and share PubSub+ API hints, new features, useful integrations, demos, and sample code!

JOIN THE DISCUSSION