Skip to content

Commit

Permalink
Add BLE beacon advertise mode setting (#1856)
Browse files Browse the repository at this point in the history
* replaced variables with values where possible

* added option to set advertise mode

* adjusted sensor description and changed the formatting

* renamed values to be more descriptive

* changed constant names to be more descriptive

* fixed and unified naming of settings, added quotes around references to specific sensor settings
  • Loading branch information
amadeo-alex committed Oct 31, 2021
1 parent ef06cf4 commit c6a5231
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
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

0 comments on commit c6a5231

Please sign in to comment.