Unit Controller

Unit Controller

Via the UnitController the app can access available and nearby units, filter by type and command them to open.
To acquire the single instance of the Unit Controller call sdk.getUnitController()

Unit Controller Status

The general status of the Unit Controller can be observed from the getStatus() method.
Possible values of UnitController.Status and their expected values are:

  • SdkNotReady: The unit controller can only operate when the SDK is ready (logged-in)
  • Ready: The SDK is ready and can be used to control units. A call to .open(iotUnit) when the controller is not on this state will throw IllegalStateException.
  • NoLocationPermissio: It’s necessary to have location permission for the controller to scan for nearby IotUnits
  • LocationIsOff: It’s necessary for the location to be on in the device settings for the controller to scan for nearby IotUnits
  • BluetoothIsOff: It’s necessary for bluetooth to be turned on for the controller to scan for nearby IotUnits
  • BluetoothError: There was an error reported by the Bluetooth radio. The error code is inside available inside this object
  • Busy: The controller is busy opening a unit after it was requested.

Get Units

To get the IotUnit’s call unitController.getUnits(Availability, Sorting, IotUnit.Type?): Flow<List<IotUnit>>. You can pass some parameters for filtering.

Parameter: Availability

Availability Api

  • All: every unit the user can have access to, regardless of specific times or bookings
  • AvailableNow: only the units the user can access at the moment. Takes in consideration opening times and if the unit is booked now. The LiveData will be updated when availability changes. For example: “Door A” availability starts at 8:00 AM and getUnits() is queried at 7:59 AM. When the minute change the data will change to reflect the newly available door.

Parameter: Sorting

Sorting Api

  • None: No sorting applied
  • Distance: From closest to out-of-reach. Check the iotUnit.isNearby() method to see if the unit is in reach.

Parameter: IotUnit.Type

IotUnit.Type Api

  • null: no filtering, return every type of unit
  • DOOR: returns only doors
  • LOCKER_BOX: returns only locker boxes

Open an IotUnit

To open an IotUnit simply call the .open().
This method can only be called when the UnitController.Status is Ready.
In case the status is not ready, the returned Response will be failed with an IllegalStateException.

The Response of the .open() call contains two parameters:
- Response.data is the IotUnit this openable was resolved to
- Response.progress is an enum with the progress of the operation.

val cancelOpen = CancellationSignal()

fun onOpenButtonClicked() {
      .openAsLiveData(iotUnit, cancelOpen)
        Observer { response ->
          // ... observe the progress, update UI
          when (response.status) {
            Response.Status.SUCCESS -> // ...
            Response.Status.FAIL -> {
              if(response.exception is UserCancelException) {
                // the SDK successfully cancelled the operation as requested by the user
              } else {
                // check for other exception
            Response.Status.EXECUTING -> // ...

fun onCancelButtonClicked() {
    cancelOpen.cancel(UserCancelException("Canceling open of $iotUnit. User request"))

override fun onStop() {
    // onStop cancel opening to avoid the UnitController to search (and be busy) forever
    cancelOpen.cancel(Exception("Canceling open of $iotUnit. Activity stop"))

class UserCancelException(message:String): Exception(message:String)


The Openable interface marks classes that can be opened by the SDK. Currently that includes:

  • IotUnit: any unit returned by the .getUnits() method can be called to open.
  • OnTap: this object is received when the SDK detects a “tap” action on the Sensorberg gateway. See Tap handling


The progress of the opening values are as follows:

opening.onProgress().observe(this, Observer {
  when (it) {
    OpeningProgress.SearchingNearby -> // sdk is trying to find the closest available unit to open
    OpeningProgress.SearchingUnit -> // sdk is searching for one specific unit to open
    OpeningProgress.Connecting -> // sdk is connecting/communicating with the unit

The opening.data will contain the IotUnit this opening is trying to open.
It’s important to remember thou, that whenever the progress of opening is SearchingNearby the IotUnit is not known and the data will be null.


The optional CancellationSignal object supplied to the open method can be managed however the client application wants.
A simple example is when there’s a dedicated opening screen and the app uses ViewModel, so the cancel would be called on exit that screen.

class OpeningViewModel : ViewModel() {

  val cancellationSignal = CancellationSignal()  

  override onCleared() {
     // cancel any `open` invoked by this view model
     cancellationSignal.cancel(MyException()) // or just use the default CanceledException()

It’s important to understand and remember thou, that canceling is a “best attempt” and the opening might still be SUCCESS.
Whenever canceling happens, status will be changed to FAIL and the exception can be found on opening.exception. The default is CanceledException