diff --git a/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/IBeaconTransmitter.kt b/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/IBeaconTransmitter.kt index f85674b0969..761ffa3b930 100644 --- a/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/IBeaconTransmitter.kt +++ b/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/IBeaconTransmitter.kt @@ -8,6 +8,7 @@ data class IBeaconTransmitter( var transmitRequested: Boolean = false, var state: String, var transmitPowerSetting: String, + var advertiseModeSetting: String, var restartRequired: Boolean = false, val manufacturer: Int = 0x004c, val beaconLayout: String = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24" diff --git a/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/TransmitterManager.kt b/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/TransmitterManager.kt index bf0734581a0..5f33f435e90 100644 --- a/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/TransmitterManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/bluetooth/ble/TransmitterManager.kt @@ -52,14 +52,13 @@ object TransmitterManager { if (!this::physicalTransmitter.isInitialized) { val parser = BeaconParser().setBeaconLayout(haTransmitter.beaconLayout) physicalTransmitter = BeaconTransmitter(context, parser) - // this setting is how frequently we emit, low power mode is 1hz, could be a setting to make faster. - physicalTransmitter.advertiseMode = AdvertiseSettings.ADVERTISE_MODE_LOW_POWER } val bluetoothOn = BluetoothAdapter.getDefaultAdapter().isEnabled if (bluetoothOn) { val beacon = buildBeacon(haTransmitter) if (!physicalTransmitter.isStarted) { physicalTransmitter.advertiseTxPowerLevel = getPowerLevel(haTransmitter) + physicalTransmitter.advertiseMode = getAdvertiseMode(haTransmitter) physicalTransmitter.startAdvertising( beacon, object : AdvertiseCallback() { @@ -88,6 +87,14 @@ object TransmitterManager { } } + private fun getAdvertiseMode(haTransmitter: IBeaconTransmitter) = + when (haTransmitter.advertiseModeSetting) { + "lowLatency" -> AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY + "balanced" -> AdvertiseSettings.ADVERTISE_MODE_BALANCED + "lowPower" -> AdvertiseSettings.ADVERTISE_MODE_LOW_POWER // explicit for code readability + else -> AdvertiseSettings.ADVERTISE_MODE_LOW_POWER + } + private fun getPowerLevel(haTransmitter: IBeaconTransmitter) = when (haTransmitter.transmitPowerSetting) { "high" -> AdvertiseSettings.ADVERTISE_TX_POWER_HIGH diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/BluetoothSensorManager.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/BluetoothSensorManager.kt index 6a6e895b7c7..3abb8439dd3 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/BluetoothSensorManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/BluetoothSensorManager.kt @@ -19,15 +19,18 @@ class BluetoothSensorManager : SensorManager { private const val SETTING_BLE_ID2 = "ble_major" private const val SETTING_BLE_ID3 = "ble_minor" private const val SETTING_BLE_TRANSMIT_POWER = "ble_transmit_power" + private const val SETTING_BLE_ADVERTISE_MODE = "ble_advertise_mode" private const val SETTING_BLE_TRANSMIT_ENABLED = "ble_transmit_enabled" private const val SETTING_BLE_ENABLE_TOGGLE_ALL = "ble_enable_toggle_all" + private const val DEFAULT_BLE_TRANSMIT_POWER = "ultraLow" - private const val DEFAULT_BLE_ID2 = "100" - private const val DEFAULT_BLE_ID3 = "1" + private const val DEFAULT_BLE_ADVERTISE_MODE = "lowPower" + private const val DEFAULT_BLE_MAJOR = "100" + private const val DEFAULT_BLE_MINOR = "1" private var priorBluetoothStateEnabled = false // private const val TAG = "BluetoothSM" - private var bleTransmitterDevice = IBeaconTransmitter("", "", "", transmitPowerSetting = "", transmitting = false, state = "", restartRequired = false) + private var bleTransmitterDevice = IBeaconTransmitter("", "", "", transmitPowerSetting = "", advertiseModeSetting = "", transmitting = false, state = "", restartRequired = false) val bluetoothConnection = SensorManager.BasicSensor( "bluetooth_connection", "sensor", @@ -50,7 +53,7 @@ class BluetoothSensorManager : SensorManager { fun enableDisableBLETransmitter(context: Context, transmitEnabled: Boolean) { val sensorDao = AppDatabase.getInstance(context).sensorDao() - var sensorEntity = sensorDao.get(bleTransmitter.id) + val sensorEntity = sensorDao.get(bleTransmitter.id) val sensorEnabled = (sensorEntity != null && sensorEntity.enabled) if (!sensorEnabled) return @@ -150,15 +153,16 @@ class BluetoothSensorManager : SensorManager { private fun updateBLEDevice(context: Context) { addSettingIfNotPresent(context, bleTransmitter, SETTING_BLE_ENABLE_TOGGLE_ALL, "toggle", "false") - var transmitActive = getSetting(context, bleTransmitter, SETTING_BLE_TRANSMIT_ENABLED, "toggle", "true").toBoolean() - var id1 = getSetting(context, bleTransmitter, SETTING_BLE_ID1, "string", UUID.randomUUID().toString()) - var id2 = getSetting(context, bleTransmitter, SETTING_BLE_ID2, "string", DEFAULT_BLE_ID2) - var id3 = getSetting(context, bleTransmitter, SETTING_BLE_ID3, "string", DEFAULT_BLE_ID3) - var transmitPower = getSetting(context, bleTransmitter, SETTING_BLE_TRANSMIT_POWER, "list", listOf("ultraLow", "low", "medium", "high"), DEFAULT_BLE_TRANSMIT_POWER) + val transmitActive = getSetting(context, bleTransmitter, SETTING_BLE_TRANSMIT_ENABLED, "toggle", "true").toBoolean() + val uuid = getSetting(context, bleTransmitter, SETTING_BLE_ID1, "string", UUID.randomUUID().toString()) + val major = getSetting(context, bleTransmitter, SETTING_BLE_ID2, "string", DEFAULT_BLE_MAJOR) + val minor = getSetting(context, bleTransmitter, SETTING_BLE_ID3, "string", DEFAULT_BLE_MINOR) + val transmitPower = getSetting(context, bleTransmitter, SETTING_BLE_TRANSMIT_POWER, "list", listOf("ultraLow", "low", "medium", "high"), DEFAULT_BLE_TRANSMIT_POWER) + val advertiseMode = getSetting(context, bleTransmitter, SETTING_BLE_ADVERTISE_MODE, "list", listOf("lowPower", "balanced", "lowLatency"), DEFAULT_BLE_ADVERTISE_MODE) bleTransmitterDevice.restartRequired = false - if (bleTransmitterDevice.uuid != id1 || bleTransmitterDevice.major != id2 || - bleTransmitterDevice.minor != id3 || bleTransmitterDevice.transmitPowerSetting != transmitPower || - bleTransmitterDevice.transmitRequested != transmitActive || + if (bleTransmitterDevice.uuid != uuid || bleTransmitterDevice.major != major || + bleTransmitterDevice.minor != minor || bleTransmitterDevice.transmitPowerSetting != transmitPower || + bleTransmitterDevice.advertiseModeSetting != advertiseMode || bleTransmitterDevice.transmitRequested != transmitActive || priorBluetoothStateEnabled != isBtOn(context) ) { bleTransmitterDevice.restartRequired = true @@ -166,10 +170,11 @@ class BluetoothSensorManager : SensorManager { // stash the current BT state to help us know if we need to restart if BT state turns from off to on priorBluetoothStateEnabled = isBtOn(context) - bleTransmitterDevice.uuid = id1 - bleTransmitterDevice.major = id2 - bleTransmitterDevice.minor = id3 + bleTransmitterDevice.uuid = uuid + bleTransmitterDevice.major = major + bleTransmitterDevice.minor = minor bleTransmitterDevice.transmitPowerSetting = transmitPower + bleTransmitterDevice.advertiseModeSetting = advertiseMode bleTransmitterDevice.transmitRequested = transmitActive } @@ -203,7 +208,8 @@ class BluetoothSensorManager : SensorManager { icon, mapOf( "id" to bleTransmitterDevice.uuid + "-" + bleTransmitterDevice.major + "-" + bleTransmitterDevice.minor, - "Transmitting power" to bleTransmitterDevice.transmitPowerSetting + "Transmitting power" to bleTransmitterDevice.transmitPowerSetting, + "Advertise mode" to bleTransmitterDevice.advertiseModeSetting ) ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86877aeed5e..bcda5adcf1e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -299,7 +299,7 @@ like to connect to: The health of the battery The current battery level of the device The current charging state of the battery - Send BLE iBeacon message every second, used to track presence around house, e.g. together with roomassistant or esp32-mqtt-room projects. Warning, this can affect battery life, particularly if the Transmit Power setting is set to High. Settings allow specifying UUID (standard UUID format), Major and Minor (should be 0 - 65535), to tailor identifiers and groups. By default this sensor is not turned on with the Enable all toggle, to avoid battery drain, there is a setting to enable this. There is also a Transmitter Power setting to help preserve battery life (use the minimum as required) and a Transmit toggle to stop or start transmitting. + Send BLE iBeacon with configured interval, used to track presence around house, e.g. together with roomassistant or esp32-mqtt-room projects.\nBy default this sensor is not turned on with the Enable all toggle, to avoid battery drain, there is a setting to enable this (\"Include when enabling all sensors\").\n\nWarning: this can affect battery life, particularly if the \"Transmitter power\" setting is set to High or \"Advertise Mode\" is set to Low latency.\nSettings allow for specifying:\n- \"UUID\" (standard UUID format), \"Major\" and \"Minor\" (should be 0 - 65535), to tailor identifiers and groups\n- \"Transmitter Power\" and \"Advertise Mode\" to help to preserve battery life (use lowest values if possible)\n\nNote:\nAdditionally a separate setting exists (\"Enable Transmitter\") to stop or start transmitting. Information about currently connected bluetooth devices Whether or not bluetooth is enabled on the device The cell number of the incoming or outgoing call @@ -571,6 +571,10 @@ like to connect to: Medium Ultra Low Enable Transmitter + Advertise mode + Low latency (10Hz) + Balanced (3Hz) + Low power (1Hz) Include when enabling all sensors Major Minor @@ -608,7 +612,7 @@ like to connect to: Missing Valid Entity Domains You must have one of the following domains in order to use this feature: cover, fan, input_boolean, light, remote, scene, script, switch Template Widget - High Accuracy Mode + High Accuracy Mode Whether or not high accuracy mode is active on the device Connect Welcome to Home Assistant Companion!