mirror of
https://github.com/mii443/prometheus-android-exporter.git
synced 2025-08-22 15:15:35 +00:00
hw sensors
This commit is contained in:
@ -18,7 +18,7 @@ class AndroidCustomExporter(private val metricEngine: MetricsEngine) : Collector
|
||||
|
||||
// metrics definitions
|
||||
// collectBatteryStatus(mfs)
|
||||
collectGps(mfs)
|
||||
// collectGps(mfs)
|
||||
collectSteps(mfs)
|
||||
|
||||
Log.d(TAG, "Metrics collected")
|
||||
@ -37,9 +37,9 @@ class AndroidCustomExporter(private val metricEngine: MetricsEngine) : Collector
|
||||
// mfs.add(batteryPercentageGauge)
|
||||
// }
|
||||
|
||||
private fun collectGps(mfs: MutableList<MetricFamilySamples>){
|
||||
//TODO
|
||||
}
|
||||
// private fun collectGps(mfs: MutableList<MetricFamilySamples>){
|
||||
// //TODO
|
||||
// }
|
||||
|
||||
private fun collectSteps(mfs: MutableList<MetricFamilySamples>){
|
||||
val gauge = GaugeMetricFamily(
|
||||
@ -51,7 +51,6 @@ class AndroidCustomExporter(private val metricEngine: MetricsEngine) : Collector
|
||||
metricEngine.hwSensorsValues().numberOfSteps?.let{
|
||||
gauge.addMetric(listOf(), it.toDouble())
|
||||
mfs.add(gauge)
|
||||
Log.d(TAG, "heeeeeeeeeeeeeeeeeeeeeeeeeeeee")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,108 +3,254 @@
|
||||
package com.birdthedeveloper.prometheus.android.exporter.worker
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.Sensor
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.hardware.Sensor
|
||||
import android.hardware.SensorManager
|
||||
import android.os.BatteryManager
|
||||
import android.app.Activity
|
||||
import android.hardware.SensorEvent
|
||||
import android.hardware.SensorEventListener
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import android.os.CpuUsageInfo
|
||||
import android.os.HardwarePropertiesManager
|
||||
import android.os.SystemClock
|
||||
import android.system.Os
|
||||
import android.system.OsConstants
|
||||
import android.util.Log
|
||||
|
||||
private const val TAG = "METRICS_ENGINE"
|
||||
|
||||
data class AxisSpecificGauge(
|
||||
val x : Double,
|
||||
val y : Double,
|
||||
val z : Double,
|
||||
)
|
||||
|
||||
class HwSensorsCache(
|
||||
var batteryChargeRatio : Double? = null,
|
||||
var numberOfSteps : Int? = null,
|
||||
|
||||
|
||||
var headingDegrees : Double? = null,
|
||||
var headingAccuracyDegrees : Double? = null,
|
||||
var hingeAngleDegrees : Double? = null,
|
||||
var offbodyDetect : Double? = null,
|
||||
var ambientTemperatureCelsius : Double? = null,
|
||||
var relativeHumidityPercent : Double? = null,
|
||||
|
||||
var accelerometer : AxisSpecificGauge? = null,
|
||||
var magneticFieldMicroTesla : AxisSpecificGauge? = null,
|
||||
var gyroscopeRadiansPerSecond: AxisSpecificGauge? = null,
|
||||
|
||||
var ambientLightLux : Double? = null,
|
||||
var pressureHectoPascal : Double? = null,
|
||||
var proximityCentimeters : Double? = null,
|
||||
|
||||
var gravityAcceleration : AxisSpecificGauge? = null,
|
||||
var linearAcceleration : AxisSpecificGauge? = null,
|
||||
var rotationVectorValues : AxisSpecificGauge? = null,
|
||||
var rotationVectorCosinusThetaHalf : Double? = null,
|
||||
var rotationVectorAccuracyRadians : Double? = null,
|
||||
);
|
||||
|
||||
//TODO for cpu, use HardwarePropertiesManager
|
||||
|
||||
private val supportedSensors : List<Int> = listOf(
|
||||
Sensor.TYPE_HEADING,
|
||||
Sensor.TYPE_HINGE_ANGLE,
|
||||
Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT,
|
||||
Sensor.TYPE_AMBIENT_TEMPERATURE,
|
||||
Sensor.TYPE_RELATIVE_HUMIDITY,
|
||||
Sensor.TYPE_ACCELEROMETER,
|
||||
Sensor.TYPE_MAGNETIC_FIELD,
|
||||
Sensor.TYPE_GYROSCOPE,
|
||||
Sensor.TYPE_LIGHT,
|
||||
Sensor.TYPE_PRESSURE,
|
||||
Sensor.TYPE_PROXIMITY,
|
||||
Sensor.TYPE_GRAVITY,
|
||||
Sensor.TYPE_LINEAR_ACCELERATION,
|
||||
Sensor.TYPE_ROTATION_VECTOR,
|
||||
)
|
||||
|
||||
val temperatureTypes : Map<Int, String> = mapOf(
|
||||
HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY to "battery",
|
||||
HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU to "cpu",
|
||||
HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU to "gpu",
|
||||
HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN to "skin",
|
||||
|
||||
)
|
||||
|
||||
class MetricsEngine(private val context: Context) : SensorEventListener {
|
||||
private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
private val hwSensorsCache = HwSensorsCache()
|
||||
val hwPropertiesManager = context.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE) as HardwarePropertiesManager
|
||||
|
||||
init {
|
||||
registerAllHwEventHandlers()
|
||||
}
|
||||
|
||||
fun hwSensorsValues() : HwSensorsCache{
|
||||
fun hwSensorsValues(): HwSensorsCache {
|
||||
return hwSensorsCache
|
||||
}
|
||||
|
||||
private fun registerAllHwEventHandlers(){
|
||||
Log.d(TAG, "Registering all hw sensors")
|
||||
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
|
||||
sensor?.let{
|
||||
Log.d(TAG, "Sensor exists!")
|
||||
private fun registerAllHwEventHandlers() {
|
||||
Log.d(TAG, "Registering all hardware sensors")
|
||||
|
||||
//TODO test registering and unregistering as optimization
|
||||
|
||||
supportedSensors.forEach { supportedSensor ->
|
||||
val sensor: Sensor? = sensorManager.getDefaultSensor(supportedSensor)
|
||||
sensor?.let {
|
||||
sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_NORMAL)
|
||||
}
|
||||
//sensorManager.flush(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
sensorManager.unregisterListener(this)
|
||||
}
|
||||
|
||||
override fun onSensorChanged(event: SensorEvent?) {
|
||||
Log.d(TAG, "Sensor Changed !!!!!!!!!!!!!!")
|
||||
if(event == null){
|
||||
if (event == null) {
|
||||
return
|
||||
}
|
||||
if (event.values == null){
|
||||
if (event.values == null) {
|
||||
return
|
||||
}
|
||||
|
||||
when(event.sensor.type){
|
||||
when (event.sensor.type) {
|
||||
Sensor.TYPE_HEADING -> {
|
||||
hwSensorsCache.headingDegrees = event.values[0].toDouble()
|
||||
hwSensorsCache.headingAccuracyDegrees = event.values[1].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_HINGE_ANGLE -> {
|
||||
hwSensorsCache.hingeAngleDegrees = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT -> {
|
||||
hwSensorsCache.offbodyDetect = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_AMBIENT_TEMPERATURE -> {
|
||||
hwSensorsCache.ambientTemperatureCelsius = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_RELATIVE_HUMIDITY -> {
|
||||
hwSensorsCache.relativeHumidityPercent = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_ACCELEROMETER -> {
|
||||
hwSensorsCache.accelerometer = valuesToAxisSpecificGauge(event.values)
|
||||
}
|
||||
|
||||
Sensor.TYPE_MAGNETIC_FIELD -> {
|
||||
hwSensorsCache.magneticFieldMicroTesla = valuesToAxisSpecificGauge(event.values)
|
||||
}
|
||||
|
||||
Sensor.TYPE_GYROSCOPE -> {
|
||||
hwSensorsCache.gyroscopeRadiansPerSecond = valuesToAxisSpecificGauge(event.values)
|
||||
}
|
||||
|
||||
Sensor.TYPE_LIGHT -> {
|
||||
hwSensorsCache.ambientLightLux = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_PRESSURE -> {
|
||||
hwSensorsCache.pressureHectoPascal = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_PROXIMITY -> {
|
||||
hwSensorsCache.numberOfSteps = event.values[0].toInt()
|
||||
hwSensorsCache.proximityCentimeters = event.values[0].toDouble()
|
||||
}
|
||||
|
||||
Sensor.TYPE_GRAVITY -> {
|
||||
hwSensorsCache.gravityAcceleration = valuesToAxisSpecificGauge(event.values)
|
||||
}
|
||||
|
||||
Sensor.TYPE_LINEAR_ACCELERATION -> {
|
||||
hwSensorsCache.linearAcceleration = valuesToAxisSpecificGauge(event.values)
|
||||
}
|
||||
|
||||
Sensor.TYPE_ROTATION_VECTOR -> {
|
||||
hwSensorsCache.rotationVectorValues = valuesToAxisSpecificGauge(event.values)
|
||||
hwSensorsCache.rotationVectorCosinusThetaHalf = event.values[3].toDouble()
|
||||
hwSensorsCache.rotationVectorAccuracyRadians = event.values[4].toDouble()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun valuesToAxisSpecificGauge(values: FloatArray): AxisSpecificGauge {
|
||||
return AxisSpecificGauge(
|
||||
x = values[0].toDouble(),
|
||||
y = values[1].toDouble(),
|
||||
z = values[2].toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
|
||||
Log.d(TAG, "Sensor accuracy changed.")
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
//TODO
|
||||
///TYPE_ACCELEROMETER Yes Yes Yes Yes
|
||||
//TYPE_AMBIENT_TEMPERATURE Yes n/a n/a n/a
|
||||
//TYPE_GRAVITY Yes Yes n/a n/a
|
||||
//TYPE_GYROSCOPE Yes Yes n/a1 n/a1
|
||||
//TYPE_LIGHT Yes Yes Yes Yes
|
||||
//TYPE_LINEAR_ACCELERATION Yes Yes n/a n/a
|
||||
//TYPE_MAGNETIC_FIELD Yes Yes Yes Yes
|
||||
//TYPE_ORIENTATION Yes2 Yes2 Yes2 Yes
|
||||
//TYPE_PRESSURE Yes Yes n/a1 n/a1
|
||||
//TYPE_PROXIMITY Yes Yes Yes Yes
|
||||
//TYPE_RELATIVE_HUMIDITY Yes n/a n/a n/a
|
||||
//TYPE_ROTATION_VECTOR Yes Yes n/a n/a
|
||||
//TYPE_TEMPERATURE
|
||||
// - hardware metrics:
|
||||
// - basic hw sensors
|
||||
// - network availability
|
||||
// - 4G, 5G
|
||||
// - gps - glonass beidou ...
|
||||
// - battery, charging
|
||||
// node exporter metrics
|
||||
// - cpu
|
||||
// - ram
|
||||
// - scrape duration
|
||||
// - bluetooth - mac bluetooth
|
||||
// - nfc
|
||||
// - storage information
|
||||
// - system information - version .. device name, doba provozu
|
||||
}
|
||||
|
||||
// public fun batteryChargeRatio(): Float {
|
||||
// val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intFilter ->
|
||||
// context.registerReceiver(null, intFilter)
|
||||
// }
|
||||
// //val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
|
||||
//
|
||||
// val batteryPct: Float? = batteryStatus?.let { intent ->
|
||||
// val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
|
||||
// val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
// level * 100 / scale.toFloat()
|
||||
// }
|
||||
//
|
||||
// batteryPct ?: return -1.0f
|
||||
// return batteryPct
|
||||
// }
|
||||
fun batteryChargeRatio(): Float {
|
||||
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intFilter ->
|
||||
context.registerReceiver(null, intFilter)
|
||||
}
|
||||
//val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
|
||||
|
||||
val batteryRatio: Float? = batteryStatus?.let { intent ->
|
||||
val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
|
||||
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
level / scale.toFloat()
|
||||
}
|
||||
|
||||
batteryRatio ?: return -1.0f
|
||||
return batteryRatio
|
||||
}
|
||||
|
||||
fun getNumberOfCpuCores(): Int {
|
||||
return Os.sysconf(OsConstants._SC_NPROCESSORS_CONF).toInt()
|
||||
}
|
||||
|
||||
fun getUptimeInSeconds(): Double {
|
||||
return SystemClock.elapsedRealtime() / 1000.0
|
||||
}
|
||||
|
||||
fun cpuUsage() : Array<CpuUsageInfo> {
|
||||
return hwPropertiesManager.cpuUsages
|
||||
}
|
||||
|
||||
fun getDeviceTemperatures() : Map<String, Double> {
|
||||
val result = mutableMapOf<String, Double>()
|
||||
temperatureTypes.keys.forEach { type ->
|
||||
val array = hwPropertiesManager.getDeviceTemperatures(
|
||||
type,
|
||||
HardwarePropertiesManager.TEMPERATURE_CURRENT
|
||||
)
|
||||
if(array.isNotEmpty()){
|
||||
result[temperatureTypes[type]!!] = array[0].toDouble()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun getAndroidOsVersion(): String{
|
||||
return Build.VERSION.RELEASE
|
||||
}
|
||||
|
||||
fun getAndroidModel(): String {
|
||||
return Build.MODEL
|
||||
}
|
||||
|
||||
fun getAndroidManufacturer() : String {
|
||||
return Build.MANUFACTURER
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ package com.birdthedeveloper.prometheus.android.exporter.worker
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.hardware.SensorManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.work.CoroutineWorker
|
||||
@ -117,6 +116,7 @@ class PromWorker(
|
||||
withContext(NonCancellable) {
|
||||
Log.v(TAG, "Canceling prom worker")
|
||||
backgroundDispatcher.close()
|
||||
metricsEngine.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user