TechnionYP5777 / Smartcity-Smarthouse

Smartcity-Smarthouse
11 stars 5 forks source link

Improve the Smarthouse API #150

Closed RonGatenio closed 7 years ago

RonGatenio commented 7 years ago

I'm opening this issue in order to summarize all of the changes that were made to the API. A wiki page will be opened on this in the future.

The main changes were:

RonGatenio commented 7 years ago

Services

Change made in 105da97abc27552c14b735ad6fda2057185db1f2

A new package system.services was created. In it you can find the 2 currently available services: SensorManager, and AlertsManager.

Before this change, the API was very messy. ApplicationHandler contained API functions that used the databaseHandler, and SmartHouseApplication contained wrappers for those functions. The functions were a mixture of sensor related functions and alert related functions.

After the change, the wrappers have been removed. The SmartHouseApplication no longer supports those functions. Instead, SmartHouseApplication supports a getService function. Given a ServiceType (an enum), this function returns a handle to the requested service.

Now, we can easily add functionality to the API by creating more independent services.

RonGatenio commented 7 years ago

SensorManager - SensorApi

Change made in 5bf3d9ae04e6cbb6f0c61a077f30c8b6119d3e8a

The SensorManager is the most important service for the applications. In this upgrade, the SensorManager was redesigned. Instead of supporting all sensors, this service now returns a sub-service, SensorApi, that allows a continues interaction with a specific sensor.

Before

Before this change, the SensorManager had an inquireAbout function that allowed the applications to receive an id of a sensor by its commercial name:

public class SosAppGui extends SmartHouseApplication {
   @Override public void onLoad() throws OnLoadException {
      SensorsManager sensorsManager = (SensorsManager) super.getService(ServiceType.SENSORS_SERVICE);

      final List<String> ids = sensorsManager.inquireAbout("iSOS");
      if (ids.isEmpty())
         throw new OnLoadException(ErrorCode.SENSOR_COM_NAME_NOT_FOUND);
      //...

Later, the sensorId will be used to interact with the sensor (e.g. subscribeToSensor):

      //...
      try {
         sensorsManager.subscribeToSensor(sensorId, SosSensor.class, sosSensor -> {
            final String t = "SOS " + (sosSensor.isPressed() ? "" : "Not ") + "Pressed";
            System.out.println("msg from app: " + t);
         });
         } catch (final SensorNotFoundException ¢) {
            throw new OnLoadException(ErrorCode.SENSOR_ID_NOT_FOUND, ¢.getMessage());
         }
   }
}

This design made the applications very messy. In every interaction with the sensor, the sensorId and the SensorData class must be passed as parameters. Also, the exception handling in the applications can be very annoying for the developer.

After

Now, all interactions with a specific sensor are done via a SensorApi object. Here is a code example:

public class SosAppGui extends SmartHouseApplication {
    @Override public void onLoad() throws Exception {
        SensorsManager sensorsManager = (SensorsManager) super.getService(ServiceType.SENSORS_SERVICE);
        SensorApi<SosSensor> sosSensor = sensorsManager.getDefaultSensor(SosSensor.class, "iSOS");
        sosSensor.subscribeToSensor(sos -> {
   System.out.println("SOS " + (sos.isPressed() ? "" : "Not ") + "Pressed");
            System.out.println("the sensors location is " + sos.getSensorLocation());
        });
    }
}

class SosSensor extends SensorData {
    private boolean pressed;
    boolean isPressed() {
        return pressed;
    }
}

The change in details:

RonGatenio commented 7 years ago

@alexvitho