

# Sync

Synchronize device state via Bluetooth.

---

## sync

Syncs the lock via Bluetooth: sets the lock's internal clock, retrieves battery level, uploads activity logs, and updates the device on the server.

### Signature

```kotlin
suspend fun sync(
    deviceId: String,
    key: String,
    timeInSeconds: Long? = null,
    getDeviceToken: String,
    storeLogsToken: String,
    updateDeviceToken: String,
    operationId: Int? = null,
): SyncResult
```

```swift
func sync(
    _ deviceId: String,
    key: String,
    getDeviceToken deviceToken: String,
    storeLogsToken storeToken: String,
    updateDeviceToken updateToken: String,
    timeInSeconds time: Int? = nil
) async throws -> SyncResult
```

### Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `deviceId` | `String` | Yes | Bluetooth device name of the lock. |
| `key` | `String` | Yes | eKey with `GET_TIME`, `SET_TIME`, `GET_BATTERY_LEVEL`, `GET_LOGS` permissions. |
| `timeInSeconds` | `Long?` | No | Unix timestamp (seconds) to set on the lock. If omitted, SDK uses last server time. |
| `getDeviceToken` | `String` | Yes | OAuth access token for fetching device info. |
| `storeLogsToken` | `String` | Yes | OAuth access token for uploading activity logs. |
| `updateDeviceToken` | `String` | Yes | OAuth access token for updating device state on the server. |
| `operationId` | `Int?` | No | Operation ID for tracking. |

### Return Type

```kotlin
data class SyncResult(val batteryLevel: Int)
```

```swift
public struct SyncResult: Sendable {
    public let batteryLevel: Int
}
```

| Field | Description |
|-------|-------------|
| `batteryLevel` | Battery level as percentage (0-100). |

### Error Codes

| Exception | Code | Description |
|-----------|------|-------------|
| `BluetoothException` | 708 | Bluetooth is off or unavailable. |
| `ConnectionException` | 12 | Device disconnected during sync. |
| `TimeoutException` | 703 | BLE operation exceeded the timeout. |
| `ApiException` | varies | Activity log upload or device update failed. |

### Example

```kotlin
try {
    val result = sdk.sync(
        deviceId = "IGM401abc123",
        key = guestKey,
        getDeviceToken = accessToken,
        storeLogsToken = accessToken,
        updateDeviceToken = accessToken,
    )
    println("Battery: ${result.batteryLevel}%")
} catch (e: IglooHomeException.ConnectionException) {
    showError("unexpected bluetooth connection issue")
} catch (e: IglooHomeException.TimeoutException) {
    showError("Timed out, try again")
} catch (e: IglooHomeException) {
    showError("Sync failed: ${e.message}")
}
```

```swift
do {
    let result = try await sdk.sync(
        "IGM401abc123",
        key: guestKey,
        getDeviceToken: accessToken,
        storeLogsToken: accessToken,
        updateDeviceToken: accessToken)
    print("Battery: \(result.batteryLevel)%")
} catch {
    showError(message: "Sync failed: \(error.localizedDescription)")
}
```

### Notes

- Sync reads all pending activity logs from the lock in a loop until no more remain.
- Logs are stored in a local database first, then batch-uploaded to the server.
- If `timeInSeconds` is omitted and no cached server time is available, the lock time is not updated.
- The three token parameters (`getDeviceToken`, `storeLogsToken`, `updateDeviceToken`) can be the same token if it has all required scopes, or different tokens with scoped permissions.

