feat: Add WiFi signal strength (RSSI) reporting for BYOD devices

- Add getWifiSignalStrength() method to AndroidDeviceInfoProvider to retrieve WiFi RSSI in dBm
- Add RSSI header parameter to TrmnlApiService.getNextDisplayData() API call
- Update TrmnlDisplayRepository to fetch and send WiFi signal strength to TRMNL API for BYOD devices
- Add ACCESS_WIFI_STATE permission to AndroidManifest.xml
- RSSI values match firmware implementation (dBm scale, -100 to 0)
- Only sends RSSI for BYOD device type to match firmware behavior

This enables the TRMNL API to receive WiFi signal strength data from Android
devices for monitoring and diagnostics, matching the functionality of the
TRMNL firmware devices.
This commit is contained in:
Hossain Khan
2026-01-31 21:10:59 -05:00
parent af65134527
commit 17bc9de8ca
4 changed files with 43 additions and 1 deletions
+1
View File
@@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name=".TrmnlDisplayMirrorApp"
@@ -75,6 +75,13 @@ class TrmnlDisplayRepository
// TEMP FIX: Use Base64 encoding to avoid relative path issue
// See https://github.com/usetrmnl/trmnl-android/issues/76#issuecomment-2980018109
// useBase64 = trmnlDeviceConfig.type == TrmnlDeviceType.BYOS, // Disabled for now
rssi =
if (trmnlDeviceConfig.type == TrmnlDeviceType.BYOD) {
// Send WiFi signal strength (RSSI) if available for BYOD devices only
androidDeviceInfoProvider.getWifiSignalStrength()
} else {
null
},
)
when (result) {
@@ -87,10 +87,13 @@ interface TrmnlApiService {
*
* NOTE: This API always loads the next plugin image from the playlist.
*
* See [API Doc](https://docs.trmnl.com/go/private-api/screens) for additional details.
*
* @param fullApiUrl The complete API URL to call
* @param accessToken The device's API key (required)
* @param deviceMacId The device's MAC address (optional)
* @param useBase64 Whether to request Base64-encoded image data (optional)
* @param rssi WiFi signal strength in dBm (optional, -100 to 0). See https://github.com/usetrmnl/trmnl-firmware/blob/main/src/api-client/display.cpp for additional references.
*
* @see getCurrentDisplayData
*/
@@ -100,6 +103,7 @@ interface TrmnlApiService {
@Header("access-token") accessToken: String,
@Header("ID") deviceMacId: String? = null,
@Header("BASE64") useBase64: Boolean? = null,
@Header("RSSI") rssi: Int? = null,
): ApiResult<TrmnlDisplayResponse, Unit>
/**
@@ -107,6 +111,8 @@ interface TrmnlApiService {
*
* NOTE: This API always loads the current plugin image from the playlist.
*
* See [API Doc](https://docs.trmnl.com/go/private-api/screens) for additional details.
*
* @see getNextDisplayData
*/
@GET
@@ -1,6 +1,7 @@
package ink.trmnl.android.util
import android.content.Context
import android.net.wifi.WifiManager
import android.os.BatteryManager
import com.squareup.anvil.annotations.optional.SingleIn
import ink.trmnl.android.di.AppScope
@@ -12,7 +13,7 @@ import javax.inject.Inject
* Provider class for accessing Android device information.
*
* This class provides utility methods to retrieve device-specific information
* such as battery level, which can be used for reporting to the TRMNL API.
* such as battery level and WiFi signal strength, which can be used for reporting to the TRMNL API.
*/
@SingleIn(AppScope::class)
class AndroidDeviceInfoProvider
@@ -36,4 +37,31 @@ class AndroidDeviceInfoProvider
Timber.e(e, "Failed to get battery level")
null
}
/**
* Gets the current WiFi signal strength (RSSI) of the Android device.
*
* RSSI (Received Signal Strength Indicator) is measured in dBm and typically
* ranges from -100 (weakest) to 0 (strongest).
*
* @return WiFi signal strength in dBm, or null if unable to retrieve or WiFi is not connected
*/
@Suppress("DEPRECATION") // WifiInfo.rssi is still the standard way to get signal strength
fun getWifiSignalStrength(): Int? =
try {
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
val wifiInfo = wifiManager?.connectionInfo
val rssi = wifiInfo?.rssi
if (rssi != null && rssi != -127) { // -127 (`INVALID_RSSI`) indicates no signal
Timber.i("Current WiFi signal strength (RSSI): $rssi dBm")
rssi
} else {
Timber.d("WiFi not connected or signal unavailable")
null
}
} catch (e: Exception) {
Timber.e(e, "Failed to get WiFi signal strength")
null
}
}