Refactor: Separate device-level and user-level API services

- Create TrmnlUserApiService for user-level (Bearer auth) endpoints
- Move getDevice() and updateDevice() to TrmnlUserApiService
- Update TrmnlApiService to focus on device-level (Access-Token) endpoints
- Remove device management endpoints from TrmnlApiService
- Add OpenAPI documentation references (https://trmnl.com/api-docs/index.html)
- Clean up imports and improve documentation

This separation clarifies authentication requirements:
- TrmnlApiService: Device API key via Access-Token header
- TrmnlUserApiService: Account API key via Bearer Authorization header
This commit is contained in:
Hossain Khan
2026-01-31 08:39:24 -05:00
parent 7bb793f372
commit 340f3399c9
3 changed files with 1222 additions and 51 deletions
@@ -3,28 +3,29 @@ package ink.trmnl.android.network
import com.slack.eithernet.ApiResult
import ink.trmnl.android.data.TrmnlDisplayRepository
import ink.trmnl.android.network.model.TrmnlCurrentImageResponse
import ink.trmnl.android.network.model.TrmnlDeviceResponse
import ink.trmnl.android.network.model.TrmnlDeviceUpdateRequest
import ink.trmnl.android.network.model.TrmnlDisplayResponse
import ink.trmnl.android.network.model.TrmnlModelsResponse
import ink.trmnl.android.network.model.TrmnlSetupResponse
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.PATCH
import retrofit2.http.Url
/**
* API service interface for TRMNL or BYOS servers.
* API service interface for TRMNL device-level API endpoints.
*
* This interface defines the endpoints for the TRMNL API.
* This interface defines endpoints that require device-level authentication via
* Access-Token header (Device API key), as opposed to user-level Bearer token authentication.
*
* For user-level (account) API endpoints, see [TrmnlUserApiService].
*
* See:
* - https://docs.usetrmnl.com/go
* - https://docs.usetrmnl.com/go/private-api/introduction
* - https://trmnl.com/api-docs/index.html (OpenAPI documentation)
*
* @see TrmnlDisplayRepository
* @see TrmnlUserApiService
*/
interface TrmnlApiService {
companion object {
@@ -64,16 +65,6 @@ interface TrmnlApiService {
* @see getDeviceModels
*/
internal const val MODELS_API_PATH = "api/models"
/**
* Path template for the TRMNL API endpoint to get or update a specific device.
*
* Replace `{id}` with the actual device ID.
*
* @see getDevice
* @see updateDevice
*/
internal const val DEVICE_API_PATH = "api/devices/{id}"
}
/**
@@ -141,39 +132,4 @@ interface TrmnlApiService {
suspend fun getDeviceModels(
@Url fullApiUrl: String,
): ApiResult<TrmnlModelsResponse, Unit>
/**
* Retrieve device data for a specific device using [DEVICE_API_PATH].
*
* This endpoint provides information about a single device including its configuration,
* battery status, WiFi strength, and sleep mode settings.
*
* @param fullApiUrl The complete API URL to call (e.g., "https://usetrmnl.com/api/devices/1")
* @param accessToken The bearer authentication token
* @return An [ApiResult] containing [TrmnlDeviceResponse] with the device data
*/
@GET
suspend fun getDevice(
@Url fullApiUrl: String,
@Header("Authorization") accessToken: String,
): ApiResult<TrmnlDeviceResponse, Unit>
/**
* Update device settings for a specific device using [DEVICE_API_PATH].
*
* This endpoint allows updating device configuration such as sleep mode settings
* and battery charge percentage.
*
* @param fullApiUrl The complete API URL to call (e.g., "https://usetrmnl.com/api/devices/1")
* @param accessToken The bearer authentication token
* @param updateRequest The device update request containing the fields to update
* @return An [ApiResult] containing [TrmnlDeviceResponse] with the updated device data
*/
@Headers("Content-Type: application/json")
@PATCH
suspend fun updateDevice(
@Url fullApiUrl: String,
@Header("Authorization") accessToken: String,
@Body updateRequest: TrmnlDeviceUpdateRequest,
): ApiResult<TrmnlDeviceResponse, Unit>
}
@@ -0,0 +1,78 @@
package ink.trmnl.android.network
import com.slack.eithernet.ApiResult
import ink.trmnl.android.network.model.TrmnlDeviceResponse
import ink.trmnl.android.network.model.TrmnlDeviceUpdateRequest
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.PATCH
import retrofit2.http.Url
/**
* API service interface for TRMNL user-level (account) API endpoints.
*
* This interface defines endpoints that require user-level authentication via Bearer token
* (Account API key), as opposed to device-level authentication.
*
* See:
* - https://docs.usetrmnl.com/go
* - https://trmnl.com/api-docs/index.html (OpenAPI documentation)
*/
interface TrmnlUserApiService {
companion object {
/**
* Path template for the TRMNL API endpoint to get or update a specific device.
*
* Replace `{id}` with the actual device ID.
*
* **Authentication:** Requires Bearer token (user-level Account API key)
*
* See: https://trmnl.com/api-docs/index.html#/Devices
*
* @see getDevice
* @see updateDevice
*/
internal const val DEVICE_API_PATH = "api/devices/{id}"
}
/**
* Retrieve device data for a specific device using [DEVICE_API_PATH].
*
* This endpoint provides information about a single device including its configuration,
* battery status, WiFi strength, and sleep mode settings.
*
* **Authentication:** Requires Bearer token with user-level Account API key
*
* @param fullApiUrl The complete API URL to call (e.g., "https://usetrmnl.com/api/devices/1")
* @param accessToken The bearer authentication token (format: "Bearer your_api_key")
* @return An [ApiResult] containing [TrmnlDeviceResponse] with the device data
*/
@GET
suspend fun getDevice(
@Url fullApiUrl: String,
@Header("Authorization") accessToken: String,
): ApiResult<TrmnlDeviceResponse, Unit>
/**
* Update device settings for a specific device using [DEVICE_API_PATH].
*
* This endpoint allows updating device configuration such as sleep mode settings
* and battery charge percentage.
*
* **Authentication:** Requires Bearer token with user-level Account API key
*
* @param fullApiUrl The complete API URL to call (e.g., "https://usetrmnl.com/api/devices/1")
* @param accessToken The bearer authentication token (format: "Bearer your_api_key")
* @param updateRequest The device update request containing the fields to update
* @return An [ApiResult] containing [TrmnlDeviceResponse] with the updated device data
*/
@Headers("Content-Type: application/json")
@PATCH
suspend fun updateDevice(
@Url fullApiUrl: String,
@Header("Authorization") accessToken: String,
@Body updateRequest: TrmnlDeviceUpdateRequest,
): ApiResult<TrmnlDeviceResponse, Unit>
}
File diff suppressed because it is too large Load Diff