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
}
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)