Skip to content

LockState and MechanismState

LockState represents the state of the lock and its component locking MechanismState(s):

class LockState { 
    Visibility visibility;
    MechanismState primary;
    MechanismState secondary;
    Boolean keypadActive
}

Visibility Represents the the known presence of the lock in range of the Scanner based on lock advertising broadcasts and SDK interactions with the lock

enum Visibility {
    Visible, // When `Visible` the lock is presumed to be
             // available for your commands based upon 
             // broadcasts or other interactions
    Unknown // When `Unknown` The SDK or its Scanner has had 
            // no recent interactions  
            // with this lock, the lock is presumed to be
            // out of range or no longer broadcasting
}
MechanismState represents the state of the locking mechanisms. Most locks have only one mechanism (e.g. the shackle on a padlock, or the open switch on a door controller.) A Portable Lock Box has two: the door on a is primary and the removable shackle is secondary. For devices that only have one MechanismState secondary will always have a MechanismState of ‘Unknown’.

In Java, access the MechanismState’s value field to access the MechanismStateOptions enum representing the current MechanismState value, and countdown() to access the current countdown value:

enum class MechanismStateOptions {
    Unknown,
    Locked,
    PendingUnlock,
    Open,
    Unlocked
}
The Java example below demonstrates how an App might consume an MLProduct’s LockState and apply it to a User Interface:
if (product.state().getVisibility().equals(Visibility.Visible)) {
    renderUIWithViewType(of(product.state().getPrimary()))

    if (product.mechanismOptions().size > 1) {
        renderUIWithViewType(of(product.state().getSecondary()))
    }
} else {
    hideUIForProduct(product)
}

static LockViewType of(MechanismState mechanismState) {
            switch (mechanismState.getValue()) {
                case Unknown:
                    return LockViewType.VisibleUnknownMechanismState;
                case Locked:
                    return LockViewType.Locked;
                case PendingUnlock:
                    return LockViewType.PendingUnlock;
                case Open:
                    return LockViewType.Open;
                case Unlocked:
                    return LockViewType.Unlocked;
            }

            return LockViewType.VisibleUnknownMechanismState;
        }

The MechanismState object is a Kotlin sealed class:

sealed class MechanismState {
    abstract val value: MechanismStateOptions

    object Unknown : MechanismState()
    object Locked : MechanismState() 
    object PendingUnlock : MechanismState() 
    object Open : MechanismState() 
    class Unlocked(val countdown: Int) : MechanismState() 
    fun countdown(): Int {
        return if (this is Unlocked) this.countdown else 0
    }
}

As a result, in Kotlin, you can take advantage of the sealed class’s exhaustive when capabilities and switch against the MechanismState itself.

For example:

fun renderUI(product: MLProduct) {
    if (product.isVisible()) {
        renderUIWithViewType(of(product.state().getPrimary()))
    }
}
fun of(mechanismState: MechanismState): LockViewType {
    return when (mechanismState) {
                MechanismState.Unknown -> LockViewType.VisibleUnknownMechanismState;
                MechanismState.Locked -> LockViewType.Locked;
                MechanismState.PendingUnlock -> LockViewType.PendingUnlock;
                MechanismState.Open -> LockViewType.Open;
                is MechanismState.Unlocked -> LockViewType.Unlocked;
            }
}

KeypadActive indicates if the lock’s physical keypad has recently been interacted with. (This is useful for implementing unlock when a user presses a button on the keypad. This will always be reset to “false” after an unlock)