Uses Bluetooth LE (via the Plugin.BLE plugin) to communicate with and manipulate an August Smart Lock. This is a rough port of the node augustcl library from @ethitter.
This Plugin was tested on Android Only! It might work on iOS, I haven't tried it but if you have an iOS device and it works, let me know.
Install-Package Plugin.Android.AugustLock
Add these permissions to AndroidManifest.xml (for Bluetooth LE). For Marshmallow and above, please follow Requesting Runtime Permissions in Android Marshmallow and don't forget to prompt the user for the location permission.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
The API operates using offline keys so that no access to the internet by the calling device or the lock is required. To obtain the keys, you must extract them from the August App. This used to be quite easy (in a debug mode in the app), but August has made it more difficult recently. In the future it may not be possible to extract the keys from the app, so do it now!
- Phone should be in developer mode
- Have installed platform tools (adb). If you need them you can get the standalone tools here
- Phone is detected by adb when connected via USB. Test by running command
adb devices
, should show something likeFA6910301551 device
under "List of devices attached" - Dump the config file from the connected phone by running:
adb shell cat /data/data/com.august.luna/shared_prefs/PeripheralInfoCache.xml
- Take note of
bluetoothAddress
(this is the device ID),handshakeKey
(aka the "offline key") andhandshakeKeyIndex
(aka the "offline key offset")
Update 12/1/17: Looks like the app has now disabled backups via the "android:allowBackup" manifest setting, so the procedure below no longer works. I'll leave it here for posterity (or if they re-enable backup in the future):
- Same steps 1-3 as in the Rooted phone instructions
- Have linux tools available. An easy way to have them is to use Git Bash, part of Git. Download Git
- Back up the app files, run:
adb backup -f backup.ab -noapk com.august.luna
- Using Git Bash:
cd
to the directory of thebackup.ab
file- Strip unnecessary data from the file, decompress it, unpack a specific file and parse it. Run:
This should output the app preferences:
dd if=backup.ab bs=24 skip=1 | openssl zlib -d | tar xv -O apps/com.august.luna/sp/PeripheralInfoCache.xml | grep -ohP '"[^&]+":(")?[^&]+(")?(?=[,}])' | sed 's/"/"/g'
"lockId":"5634B1E5A9DFD49C5897FBF53388C0FA" "bluetoothAddress":"CE:78:1E:AA:EB:94" "handshakeKey":"119FFA3E1AF914203303DBEDBC59F161" "handshakeKeyIndex":1 "serialNumber":"L1GFSED420" "armFirmwareVersion":"1.0.192" "bluetoothFirmwareVersion":"1.1.20" "gitHashFirmwareVersion":"834c0380" "batteryLevel":"HIGH" "peripheralType":"Lock"
- Take note of
bluetoothAddress
(this is the device ID),handshakeKey
(aka the "offline key") andhandshakeKeyIndex
(aka the "offline key offset")
Update: Looks like this no longer works, I'll leave it here for posterity:
The key and offset can be found in plist located at:
User Applications/August/Library/Preferences/com.august.iossapp.plist
This can be retrieved by using a file explorer like iFunbox, and opening the plist in Xcode.
private static async Task LockOrUnlock(string id, string key, int keyOffset)
{
var august = new AugustLockDevice(id, key, keyOffset);
if (await august.Connect())
{
try
{
await august.Toggle();
}
finally
{
await august.Disconnect();
}
}
else
{
// out of range, timeout or other error...
}
}
// example invocation. NOTE: can pass in "0" for the ID if it is not known
LockOrUnlock("CE781EAAEB94", "119FFA3E1AF914203303DBEDBC59F161", 1);
If you want to see the debug output, hook up to the Debug EventHandler:
var august = new AugustLockDevice(...);
august.DebugMessage += (src, msg) => Android.Util.Log.Debug("August", msg);
If you do not know the device's ID (the bluetooth address, strip out the ":" characters) but you do know the key and key offset, you can pass in "0" as the ID to the AugustLockDevice and it will try to use the key & offset provided on any lock it finds. If you output the debug messages you should be able to see the device ID which you can use in the future to prevent connecting to the wrong lock if you have multiple locks in range.
Depending on your phone and lock bluetooth reception (based what times out on the debug output), you may want to tweak the timeouts for scanning/connecting/etc:
var august = new AugustLockDevice(...);
august.ScanTimeout = 7000; // timeouts are in milliseconds
august.ConnectTimeout = 7000;
august.CommandTimeout = 3000;