Skip to content

Android SDK

The Tessol Android SDK exposes TessolCommandController for controlling compatible devices over Bluetooth Low Energy (BLE), synchronizing time, reading temperature data, and uploading records. This guide targets the current stable SDK, 1.0.8.

  • Android API level 24 or newer
  • A BLE-capable Android device
  • A provisioned AWS IoT device certificate and matching PKCS#8 private key
  • Runtime Bluetooth permissions; location permission is also required for BLE scanning on some Android versions before Android 12
  • Internet access when uploading records

Request certificates and compatible device details from TAMsys support.

Add Maven Central and the SDK dependency to your Android project:

build.gradle.kts
repositories {
google()
mavenCentral()
}
dependencies {
implementation("in.tessol.tamsys:tamsys-sdk:1.0.8")
}

For a Groovy build file:

build.gradle
dependencies {
implementation "in.tessol.tamsys:tamsys-sdk:1.0.8"
}

The release is published as in.tessol.tamsys:tamsys-sdk:1.0.8 on Maven Central.

The host app is responsible for declaring and requesting BLE permissions. Use the permissions that apply to your target SDK and scanning behavior; this is a minimal baseline for scanning and connecting:

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<!-- Android 12 (API 31) and newer -->
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Android 11 (API 30) and older -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
</manifest>

Manifest declarations do not grant dangerous permissions. Request the applicable permissions at runtime before scanning or issuing device commands, and explain the request in your UI.

  1. Import the public API

    import `in`.tessol.tamsys.v2.sdk.TessolCommandController
    import `in`.tessol.tamsys.v2.sdk.TessolSdk
    import `in`.tessol.tamsys.v2.sdk.data.model.AwsConfigs
  2. Initialize once at application startup

    Provide the device certificate and PKCS#8 private key as streams before calling any other SDK functionality:

    TessolSdk.initialize(
    AwsConfigs(
    deviceCertInputStream = context.assets.open("device-certificate.pem"),
    privateKeyInputStream = context.assets.open("private_key_pkcs8.pem")
    )
    )
  3. Create and retain a controller for the device workflow

    val controller = TessolCommandController.getInstance(context)

Controller operations are suspending functions that return Kotlin Result<T>. Call them from a coroutine and handle both branches:

lifecycleScope.launch {
controller.getSystemInfo(deviceId)
.onSuccess { systemInfo ->
// Update the UI with systemInfo.
}
.onFailure { error ->
// Show a recoverable error state.
}
}

Most one-shot BLE commands retry up to three times within a default total timeout of 30 seconds. Record synchronization has the separate timeout constraint described below.

Every device operation requires the exact deviceId: String assigned to the compatible Tessol device.

val startResult = controller.startOperation(deviceId)
val stopResult = controller.stopOperation(deviceId)
val timeResult = controller.getTime(deviceId)
val setTimeResult = controller.setTime(
deviceId = deviceId,
time = System.currentTimeMillis()
)
val intervalResult = controller.setInterval(
deviceId = deviceId,
intervalSeconds = 60
)

Use a positive interval in multiples of 5 seconds.

val systemInfoResult = controller.getSystemInfo(deviceId)

System information can include firmware version, stored data point count, and other device metadata.

val resetResult = controller.factoryReset(deviceId)
val temperatureResult = controller.getCurrentTemp(deviceId)

The controller can return its most recently fetched current-temperature value for up to one minute. When one app works with multiple devices, retain a separate controller for each device workflow rather than alternating device IDs on one controller.

Use the V2 record retrieval API and allow at least 90 seconds for the complete operation:

val syncResult = controller.saveRecordsFromDeviceV2(
deviceId = deviceId,
timeoutMs = 120_000L
)

On success, the result contains the number of records saved in the SDK’s local database. Successfully processed sectors are then erased from the device. Do not terminate the operation midway, and surface failures so the user can retry safely.

Upload all records currently stored in the SDK’s local database:

val uploadResult = controller.uploadRecordsFromDevice()

Attach application-specific data to every uploaded record when needed:

val extraData = mapOf(
"batteryVoltage" to "1",
"longitude" to "76.6897041",
"latitude" to "30.7075106"
)
val uploadResult = controller.uploadRecordsFromDevice(
extraData = extraData
)

The result contains the uploaded record count. The SDK removes local records only after a successful upload. SDK 1.0.8 publishes uploads to TAMsys through the AWS IoT Core HTTPS device API.

To read and immediately upload one current temperature record:

val uploadResult = controller.uploadCurrentTemperature(
deviceId = deviceId,
extraData = extraData
)

The sample app’s CommandsActivityPublicSDK demonstrates command buttons, interval prompts, loading states, and success or failure dialogs.

Command Action
SystemInfo Fetch system data
SetInterval Set the logging interval
GetTime Fetch device time
SetTime Set device time to the Android system time
StartOperation Start device operation
StopOperation Stop device operation
GetCurrentTemperature Fetch the latest temperature
GetStoredSensorData Retrieve stored temperature data
UploadData Upload stored data
FactoryReset Reset the device
  • Use SDK 1.0.8 or explicitly validate the API differences before pinning another version.
  • Initialize the SDK once before creating a controller.
  • Declare and request the platform-appropriate BLE permissions.
  • Run controller operations in a lifecycle-aware coroutine scope.
  • Handle both success and failure from every Result<T>.
  • Use saveRecordsFromDeviceV2() with a timeout of at least 90 seconds.
  • Treat device certificates and private keys as sensitive credentials.

Reference UI and usage flow: Tessol Android sample app README, updated for SDK 1.0.8. Dependency version, public signatures, timeout constraints, and lifecycle behavior on this page were cross-checked against the published SDK 1.0.8 artifact and its source JAR.