From 553d5e5cc3a3343a28c876f294536504a2c1f6a5 Mon Sep 17 00:00:00 2001 From: Daniel Shokouhi Date: Sun, 20 Sep 2020 11:19:14 -0700 Subject: [PATCH] Add traffic stat sensors mobile and total data usage for transmitting and receving (#961) * Add traffic stat sensors mobile and total data usage for transmitting and receiving * Review comments --- .../android/sensors/SensorReceiver.kt | 3 +- .../android/sensors/TrafficStatsManager.kt | 177 ++++++++++++++++++ app/src/main/res/values/strings.xml | 9 + 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/io/homeassistant/companion/android/sensors/TrafficStatsManager.kt diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt index b89494d48..9fcea0f6d 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt @@ -37,7 +37,8 @@ class SensorReceiver : BroadcastReceiver() { PressureSensorManager(), ProximitySensorManager(), StepsSensorManager(), - StorageSensorManager() + StorageSensorManager(), + TrafficStatsManager() ) const val ACTION_REQUEST_SENSORS_UPDATE = diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/TrafficStatsManager.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/TrafficStatsManager.kt new file mode 100644 index 000000000..774b827bb --- /dev/null +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/TrafficStatsManager.kt @@ -0,0 +1,177 @@ +package io.homeassistant.companion.android.sensors + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.net.TrafficStats +import android.util.Log +import io.homeassistant.companion.android.R +import java.math.RoundingMode +import kotlin.math.absoluteValue + +class TrafficStatsManager : SensorManager { + companion object { + private const val TAG = "TrafficStats" + private const val GB = 1000000000 + + val rxBytesMobile = SensorManager.BasicSensor( + "mobile_rx_gb", + "sensor", + R.string.basic_sensor_name_mobile_rx_gb, + R.string.sensor_description_mobile_rx_gb, + unitOfMeasurement = "GB" + ) + val txBytesMobile = SensorManager.BasicSensor( + "mobile_tx_gb", + "sensor", + R.string.basic_sensor_name_mobile_tx_gb, + R.string.sensor_description_mobile_tx_gb, + unitOfMeasurement = "GB" + ) + val rxBytesTotal = SensorManager.BasicSensor( + "total_rx_gb", + "sensor", + R.string.basic_sensor_name_total_rx_gb, + R.string.sensor_description_total_rx_gb, + unitOfMeasurement = "GB" + ) + val txBytesTotal = SensorManager.BasicSensor( + "total_tx_gb", + "sensor", + R.string.basic_sensor_name_total_tx_gb, + R.string.sensor_description_total_tx_gb, + unitOfMeasurement = "GB" + ) + private var hasCellular = false + } + + override val enabledByDefault: Boolean + get() = false + override val name: Int + get() = R.string.sensor_name_traffic_stats + + override val availableSensors: List + get() = if (hasCellular) { + listOf(rxBytesMobile, txBytesMobile, rxBytesTotal, txBytesTotal) + } else listOf(rxBytesTotal, txBytesTotal) + + override fun requiredPermissions(): Array { + return emptyArray() + } + + override fun hasSensor(context: Context): Boolean { + val cm: ConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val networkInfo = cm.allNetworks + var networkCapabilities: NetworkCapabilities + for (item in networkInfo) { + networkCapabilities = cm.getNetworkCapabilities(item) + if (!hasCellular) + hasCellular = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) + } + return true + } + override fun requestSensorUpdate( + context: Context + ) { + updateMobileRxBytes(context) + updateMobileTxBytes(context) + updateTotalRxBytes(context) + updateTotalTxBytes(context) + } + + private fun updateMobileRxBytes(context: Context) { + + if (!isEnabled(context, rxBytesMobile.id)) + return + + var mobileRx = 0f + val icon = "mdi:radio-tower" + + try { + mobileRx = TrafficStats.getMobileRxBytes().toFloat() + } catch (e: Exception) { + Log.e(TAG, "Error getting the mobile rx bytes", e) + return + } + + mobileRx /= GB + onSensorUpdated(context, + rxBytesMobile, + mobileRx.toBigDecimal().setScale(3, RoundingMode.HALF_EVEN), + icon, + mapOf() + ) + } + + private fun updateMobileTxBytes(context: Context) { + + if (!isEnabled(context, txBytesMobile.id)) + return + + var mobileTx = 0f + val icon = "mdi:radio-tower" + + try { + mobileTx = TrafficStats.getMobileTxBytes().toFloat() + } catch (e: Exception) { + Log.e(TAG, "Error getting the mobile tx bytes", e) + return + } + + mobileTx /= GB + onSensorUpdated(context, + txBytesMobile, + mobileTx.toBigDecimal().setScale(3, RoundingMode.HALF_EVEN), + icon, + mapOf() + ) + } + private fun updateTotalRxBytes(context: Context) { + + if (!isEnabled(context, rxBytesTotal.id)) + return + + var totalRx = 0f + val icon = "mdi:radio-tower" + + try { + totalRx = TrafficStats.getTotalRxBytes().toFloat().absoluteValue + } catch (e: Exception) { + Log.e(TAG, "Error getting the total rx bytes", e) + return + } + totalRx /= GB + + onSensorUpdated(context, + rxBytesTotal, + totalRx.toBigDecimal().setScale(3, RoundingMode.HALF_EVEN), + icon, + mapOf() + ) + } + + private fun updateTotalTxBytes(context: Context) { + + if (!isEnabled(context, txBytesTotal.id)) + return + + var totalTx = 0f + val icon = "mdi:radio-tower" + + try { + totalTx = TrafficStats.getTotalTxBytes().toFloat().absoluteValue + } catch (e: Exception) { + Log.e(TAG, "Error getting the total tx bytes", e) + return + } + + totalTx /= GB + + onSensorUpdated(context, + txBytesTotal, + totalTx.toBigDecimal().setScale(3, RoundingMode.HALF_EVEN), + icon, + mapOf() + ) + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9e0cc54b..53822c2c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,6 +21,10 @@ Authentication Error The \'Username\' and \'Password\' fields must be completed Authentication Requested + Mobile Rx GB + Mobile Tx GB + Total Rx GB + Total Tx GB Detected Activity Next Alarm Battery Health @@ -169,6 +173,10 @@ for Home Assistant like to connect to: Sensor Description + Total Rx GB on cellular data since last device reboot + Total Tx GB on cellular data since last device reboot + Total Rx GB since last device reboot + Total Tx GB since last device reboot The state of the devices audio mode The state of the devices ringer mode The health of the battery @@ -215,6 +223,7 @@ like to connect to: The current link speed of the device to the connected network The signal strength of the device to the WiFi network Whether or not WiFi is enabled on the device + Traffic Stats Sensors Activity Sensors Alarm Sensor Audio Sensors