Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NFC state sensor #3905

Merged
merged 10 commits into from
Oct 5, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.media.AudioManager
import android.net.wifi.WifiManager
import android.nfc.NfcAdapter
import android.os.Build
import android.os.PowerManager
import android.telephony.TelephonyManager
Expand Down Expand Up @@ -141,6 +142,12 @@ open class HomeAssistantApplication : Application() {
IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
)

// Listen for NFC state changes
registerReceiver(
sensorReceiver,
IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)
)

// Listen to changes to the audio input/output on the device
registerReceiver(
sensorReceiver,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.net.wifi.WifiManager
import android.nfc.NfcAdapter
import android.os.PowerManager
import dagger.hilt.android.AndroidEntryPoint
import io.homeassistant.companion.android.BuildConfig
Expand All @@ -24,6 +25,7 @@ import io.homeassistant.companion.android.common.sensors.LightSensorManager
import io.homeassistant.companion.android.common.sensors.MobileDataManager
import io.homeassistant.companion.android.common.sensors.NetworkSensorManager
import io.homeassistant.companion.android.common.sensors.NextAlarmManager
import io.homeassistant.companion.android.common.sensors.NfcSensorManager
import io.homeassistant.companion.android.common.sensors.PhoneStateSensorManager
import io.homeassistant.companion.android.common.sensors.PowerSensorManager
import io.homeassistant.companion.android.common.sensors.PressureSensorManager
Expand Down Expand Up @@ -72,6 +74,7 @@ class SensorReceiver : SensorReceiverBase() {
LocationSensorManager(),
MobileDataManager(),
NetworkSensorManager(),
NfcSensorManager(),
NextAlarmManager(),
NotificationSensorManager(),
PhoneStateSensorManager(),
Expand Down Expand Up @@ -113,7 +116,8 @@ class SensorReceiver : SensorReceiverBase() {
AudioManager.RINGER_MODE_CHANGED_ACTION to AudioSensorManager.audioSensor.id,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE to DevicePolicyManager.isWorkProfile.id,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE to DevicePolicyManager.isWorkProfile.id,
WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id
WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id,
NfcAdapter.ACTION_ADAPTER_STATE_CHANGED to NfcSensorManager.nfcStateSensor.id
)

override fun getSensorSettingsIntent(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.homeassistant.companion.android.common.sensors

import android.content.Context
import android.nfc.NfcAdapter
import io.homeassistant.companion.android.common.R as commonR

class NfcSensorManager : SensorManager {
companion object {
private const val TAG = "NfcSensor"

val nfcStateSensor = SensorManager.BasicSensor(
"nfc_state",
"binary_sensor",
commonR.string.basic_sensor_name_nfc_state,
commonR.string.sensor_description_nfc_state,
"mdi:nfc-variant",
entityCategory = SensorManager.ENTITY_CATEGORY_DIAGNOSTIC,
updateType = SensorManager.BasicSensor.UpdateType.INTENT
)
}

override fun docsLink() = "https://companion.home-assistant.io/docs/core/sensors#nfc-state-sensor"
override val name = commonR.string.sensor_name_nfc

override suspend fun getAvailableSensors(context: Context) = listOf(nfcStateSensor)

override fun requiredPermissions(sensorId: String) = emptyArray<String>()

override fun requestSensorUpdate(context: Context) = updateNfcState(context)

override fun hasSensor(context: Context): Boolean {
return NfcAdapter.getDefaultAdapter(context) != null
}

private fun updateNfcState(context: Context) {
if (!isEnabled(context, nfcStateSensor)) {
return
}

val nfcAdapter = NfcAdapter.getDefaultAdapter(context)
val nfcEnabled = nfcAdapter?.isEnabled == true

onSensorUpdated(
context,
nfcStateSensor,
nfcEnabled,
nfcStateSensor.statelessIcon,
emptyMap()
)
}
}
3 changes: 3 additions & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<string name="basic_sensor_name_mobile_data">Mobile data</string>
<string name="basic_sensor_name_mobile_rx_gb">Mobile Rx GB</string>
<string name="basic_sensor_name_mobile_tx_gb">Mobile Tx GB</string>
<string name="basic_sensor_name_nfc_state">NFC state</string>
<string name="basic_sensor_name_phone">Phone state</string>
<string name="basic_sensor_name_power_save">Power save</string>
<string name="basic_sensor_name_public_ip">Public IP address</string>
Expand Down Expand Up @@ -611,6 +612,7 @@
<string name="sensor_description_mobile_tx_gb">Total Tx GB on cellular data since last device reboot</string>
<string name="sensor_description_music_active">Whether music is actively playing on the device</string>
<string name="sensor_description_next_alarm">The date and time of the next scheduled alarm, any app or manufacturer can override the default behavior. The package attribute will tell you which app set the next scheduled alarm. The setting below will create an Allow List so you can specify what packages you want the alarm event from. This will ignore alarm events for packages not selected and the state will not update until the next scheduled alarm matches one of the selected packages.</string>
<string name="sensor_description_nfc_state">Whether NFC is enabled on the device</string>
<string name="sensor_description_none">No description</string>
<string name="sensor_description_phone_state">Whether the phone is ringing or in a call, no other caller information is stored</string>
<string name="sensor_description_power_save">Whether the device is in Power Save mode</string>
Expand Down Expand Up @@ -1124,6 +1126,7 @@
<string name="sensor_description_daily_calories">The total number of calories over a day (including both BMR and active calories), where the previous day ends and a new day begins at 12:00 AM local time.</string>
<string name="sensor_name_daily_steps">Daily steps</string>
<string name="sensor_description_daily_steps">The total step count over a day, where the previous day ends and a new day begins at 12:00 AM local time.</string>
<string name="sensor_name_nfc">NFC sensor</string>
<string name="thread_debug">Sync Thread credentials</string>
<string name="thread_debug_active">Syncing…</string>
<string name="thread_debug_result_error">An unexpected error occurred while syncing</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.media.AudioManager
import android.net.wifi.WifiManager
import android.nfc.NfcAdapter
import android.os.Build
import android.os.PowerManager
import dagger.hilt.android.HiltAndroidApp
Expand Down Expand Up @@ -100,6 +101,12 @@ open class HomeAssistantApplication : Application() {
IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
)

// Listen for NFC state changes
registerReceiver(
sensorReceiver,
IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)
)

// Update complications when the screen is on
val complicationReceiver = ComplicationReceiver()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.net.wifi.WifiManager
import android.nfc.NfcAdapter
import android.os.Build
import android.os.PowerManager
import androidx.core.app.TaskStackBuilder
Expand All @@ -27,6 +28,7 @@ import io.homeassistant.companion.android.common.sensors.LightSensorManager
import io.homeassistant.companion.android.common.sensors.MobileDataManager
import io.homeassistant.companion.android.common.sensors.NetworkSensorManager
import io.homeassistant.companion.android.common.sensors.NextAlarmManager
import io.homeassistant.companion.android.common.sensors.NfcSensorManager
import io.homeassistant.companion.android.common.sensors.PhoneStateSensorManager
import io.homeassistant.companion.android.common.sensors.PowerSensorManager
import io.homeassistant.companion.android.common.sensors.PressureSensorManager
Expand Down Expand Up @@ -71,6 +73,7 @@ class SensorReceiver : SensorReceiverBase() {
MobileDataManager(),
NetworkSensorManager(),
NextAlarmManager(),
NfcSensorManager(),
OnBodySensorManager(),
PhoneStateSensorManager(),
PowerSensorManager(),
Expand Down Expand Up @@ -116,7 +119,8 @@ class SensorReceiver : SensorReceiverBase() {
"com.google.android.clockwork.actions.WET_MODE_ENDED" to WetModeSensorManager.wetModeSensor.id,
"android.bluetooth.device.action.ACL_CONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
"android.bluetooth.device.action.ACL_DISCONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id
BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id,
NfcAdapter.ACTION_ADAPTER_STATE_CHANGED to NfcSensorManager.nfcStateSensor.id
)

override fun getSensorSettingsIntent(
Expand Down