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 BLE beacon advertise mode setting #1856

Merged
merged 6 commits into from Oct 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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"
Expand Down
Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down
Expand Up @@ -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",
Expand All @@ -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
Expand Down Expand Up @@ -150,26 +153,28 @@ 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
}
// 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
}

Expand Down Expand Up @@ -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
)
)
}
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/res/values/strings.xml
Expand Up @@ -299,7 +299,7 @@ like to connect to:</string>
<string name="sensor_description_battery_health">The health of the battery</string>
<string name="sensor_description_battery_level">The current battery level of the device</string>
<string name="sensor_description_battery_state">The current charging state of the battery</string>
<string name="sensor_description_bluetooth_ble_emitter">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. </string>
<string name="sensor_description_bluetooth_ble_emitter">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.</string>
<string name="sensor_description_bluetooth_connection">Information about currently connected bluetooth devices</string>
<string name="sensor_description_bluetooth_state">Whether or not bluetooth is enabled on the device</string>
<string name="sensor_description_call_number">The cell number of the incoming or outgoing call</string>
Expand Down Expand Up @@ -571,6 +571,10 @@ like to connect to:</string>
<string name="sensor_setting_ble_transmit_power_medium_label">Medium</string>
<string name="sensor_setting_ble_transmit_power_ultraLow_label">Ultra Low</string>
<string name="sensor_setting_ble_transmit_enabled_title">Enable Transmitter</string>
<string name="sensor_setting_ble_advertise_mode_title">Advertise mode</string>
<string name="sensor_setting_ble_advertise_mode_lowLatency_label">Low latency (10Hz)</string>
<string name="sensor_setting_ble_advertise_mode_balanced_label">Balanced (3Hz)</string>
<string name="sensor_setting_ble_advertise_mode_lowPower_label">Low power (1Hz)</string>
<string name="sensor_setting_ble_enable_toggle_all_title">Include when enabling all sensors</string>
<string name="sensor_setting_ble_major_title">Major</string>
<string name="sensor_setting_ble_minor_title">Minor</string>
Expand Down Expand Up @@ -608,7 +612,7 @@ like to connect to:</string>
<string name="tile_missing_entity_title">Missing Valid Entity Domains</string>
<string name="tile_missing_entity_summary">You must have one of the following domains in order to use this feature: cover, fan, input_boolean, light, remote, scene, script, switch</string>
<string name="template_widget">Template Widget</string>
<string name="basic_sensor_name_high_accuracy_mode">High Accuracy Mode</string>
<string name="basic_sensor_name_high_accuracy_mode">High Accuracy Mode</string>
<string name="sensor_description_high_accuracy_mode">Whether or not high accuracy mode is active on the device</string>
<string name="connect">Connect</string>
<string name="welcome_hass">Welcome to Home Assistant Companion!</string>
Expand Down