Add BLE Transmitter setting to turn on / off transmitter. (#1413)

* Add BLE Transmitter setting to turn on / off transmitter.  Notification command will now toggle the transmitter and this setting, if the sensor is enabled.

* Change setting names they're ordered correctly.  This is a slight breaking change, as people previously stored IDs will neeed to be re-added.

* Revert 'id' from labels.
This commit is contained in:
Alfiegerner 2021-03-10 11:06:32 +13:00 committed by GitHub
parent 588fc61d0c
commit d971d50941
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 29 deletions

View file

@ -5,8 +5,9 @@ data class IBeaconTransmitter(
var major: String,
var minor: String,
var transmitting: Boolean = false,
var transmitRequested: Boolean = false,
var state: String,
var transmitPower: String,
var transmitPowerSetting: 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"

View file

@ -52,14 +52,14 @@ 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
}
physicalTransmitter.advertiseTxPowerLevel = getPowerLevel(haTransmitter)
val bluetoothOn = BluetoothAdapter.getDefaultAdapter().isEnabled
if (bluetoothOn) {
val beacon = buildBeacon(haTransmitter)
if (!physicalTransmitter.isStarted) {
physicalTransmitter.advertiseTxPowerLevel
physicalTransmitter.advertiseTxPowerLevel = getPowerLevel(haTransmitter)
physicalTransmitter.startAdvertising(beacon, object : AdvertiseCallback() {
override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
haTransmitter.transmitting = true
@ -86,9 +86,9 @@ object TransmitterManager {
}
private fun getPowerLevel(haTransmitter: IBeaconTransmitter): Int {
if (haTransmitter.transmitPower == "high") return AdvertiseSettings.ADVERTISE_TX_POWER_HIGH
if (haTransmitter.transmitPower == "medium") return AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM
if (haTransmitter.transmitPower == "low") return AdvertiseSettings.ADVERTISE_TX_POWER_LOW
if (haTransmitter.transmitPowerSetting == "high") return AdvertiseSettings.ADVERTISE_TX_POWER_HIGH
if (haTransmitter.transmitPowerSetting == "medium") return AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM
if (haTransmitter.transmitPowerSetting == "low") return AdvertiseSettings.ADVERTISE_TX_POWER_LOW
return AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW
}

View file

@ -7,7 +7,7 @@ import io.homeassistant.companion.android.bluetooth.BluetoothUtils
import io.homeassistant.companion.android.bluetooth.ble.IBeaconTransmitter
import io.homeassistant.companion.android.bluetooth.ble.TransmitterManager
import io.homeassistant.companion.android.database.AppDatabase
import io.homeassistant.companion.android.database.sensor.Sensor
import io.homeassistant.companion.android.database.sensor.Setting
import java.util.UUID
import kotlin.collections.ArrayList
@ -18,6 +18,7 @@ class BluetoothSensorManager : SensorManager {
private const val BLE_ID2 = "Major"
private const val BLE_ID3 = "Minor"
private const val BLE_TRANSMIT_POWER = "transmit_power"
private const val BLE_TRANSMIT_ACTIVE = "Enable Transmitter"
private const val ENABLE_TOGGLE_ALL = "Include when enabling all sensors"
private const val DEFAULT_BLE_TRANSMIT_POWER = "ultraLow"
private const val DEFAULT_BLE_ID2 = "100"
@ -25,7 +26,7 @@ class BluetoothSensorManager : SensorManager {
private var priorBluetoothStateEnabled = false
// private const val TAG = "BluetoothSM"
private var bleTransmitterDevice = IBeaconTransmitter("", "", "", transmitPower = "", transmitting = false, state = "", restartRequired = false)
private var bleTransmitterDevice = IBeaconTransmitter("", "", "", transmitPowerSetting = "", transmitting = false, state = "", restartRequired = false)
val bluetoothConnection = SensorManager.BasicSensor(
"bluetooth_connection",
"sensor",
@ -46,20 +47,18 @@ class BluetoothSensorManager : SensorManager {
R.string.sensor_description_bluetooth_ble_emitter
)
fun enableDisableBLETransmitter(context: Context, enabled: Boolean) {
fun enableDisableBLETransmitter(context: Context, transmitEnabled: Boolean) {
val sensorDao = AppDatabase.getInstance(context).sensorDao()
var sensorEntity = sensorDao.get(bleTransmitter.id)
if (sensorEntity != null) {
sensorEntity.enabled = enabled
sensorDao.update(sensorEntity)
} else {
sensorEntity = Sensor(bleTransmitter.id, enabled, false, "")
sensorDao.add(sensorEntity)
}
val sensorEnabled = (sensorEntity != null && sensorEntity.enabled)
if (!sensorEnabled)
return
TransmitterManager.stopTransmitting(bleTransmitterDevice) // stop in all instances, clean up state if start required
if (enabled) {
if (transmitEnabled) {
TransmitterManager.startTransmitting(context, bleTransmitterDevice)
}
sensorDao.add(Setting(bleTransmitter.id, BLE_TRANSMIT_ACTIVE, transmitEnabled.toString(), "toggle"))
}
}
@ -79,7 +78,7 @@ class BluetoothSensorManager : SensorManager {
) {
updateBluetoothConnectionSensor(context)
updateBluetoothState(context)
updateBLETransmitter(context)
updateBLESensor(context)
}
private fun updateBluetoothConnectionSensor(context: Context) {
@ -143,15 +142,16 @@ class BluetoothSensorManager : SensorManager {
private fun updateBLEDevice(context: Context) {
addSettingIfNotPresent(context, bleTransmitter, ENABLE_TOGGLE_ALL, "toggle", "false")
var transmitActive = getSetting(context, bleTransmitter, BLE_TRANSMIT_ACTIVE, "toggle", "true").toBoolean()
var id1 = getSetting(context, bleTransmitter, BLE_ID1, "string", UUID.randomUUID().toString())
var id2 = getSetting(context, bleTransmitter, BLE_ID2, "string", DEFAULT_BLE_ID2)
var id3 = getSetting(context, bleTransmitter, BLE_ID3, "string", DEFAULT_BLE_ID3)
var transmitPower = getSetting(context, bleTransmitter, BLE_TRANSMIT_POWER, "list", DEFAULT_BLE_TRANSMIT_POWER)
bleTransmitterDevice.restartRequired = false
if (bleTransmitterDevice.uuid != id1 || bleTransmitterDevice.major != id2 ||
bleTransmitterDevice.minor != id3 || bleTransmitterDevice.transmitPower != transmitPower ||
isBtOn(context) != priorBluetoothStateEnabled) {
bleTransmitterDevice.minor != id3 || bleTransmitterDevice.transmitPowerSetting != transmitPower ||
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
@ -160,23 +160,28 @@ class BluetoothSensorManager : SensorManager {
bleTransmitterDevice.uuid = id1
bleTransmitterDevice.major = id2
bleTransmitterDevice.minor = id3
bleTransmitterDevice.transmitPower = transmitPower
bleTransmitterDevice.transmitPowerSetting = transmitPower
bleTransmitterDevice.transmitRequested = transmitActive
}
private fun updateBLETransmitter(context: Context) {
private fun updateBLESensor(context: Context) {
// get device details from settings
updateBLEDevice(context)
// sensor disabled, stop transmitting if we have been
if (!isEnabled(context, bleTransmitter.id)) {
TransmitterManager.stopTransmitting(bleTransmitterDevice)
return
}
// transmit when BT is on, if we are not already transmitting, or details have changed
updateBLEDevice(context)
if (isBtOn(context)) {
if (!bleTransmitterDevice.transmitting || bleTransmitterDevice.restartRequired) {
if (bleTransmitterDevice.transmitRequested && (!bleTransmitterDevice.transmitting || bleTransmitterDevice.restartRequired)) {
TransmitterManager.startTransmitting(context, bleTransmitterDevice)
}
} else {
// BT off, stop transmitting if we have been
}
// BT off, or TransmitToggled off, stop transmitting if we have been
if (!isBtOn(context) || !bleTransmitterDevice.transmitRequested) {
TransmitterManager.stopTransmitting(bleTransmitterDevice)
}
@ -189,7 +194,7 @@ class BluetoothSensorManager : SensorManager {
icon,
mapOf(
"id" to bleTransmitterDevice.uuid + "-" + bleTransmitterDevice.major + "-" + bleTransmitterDevice.minor,
"Transmitting power" to bleTransmitterDevice.transmitPower
"Transmitting power" to bleTransmitterDevice.transmitPowerSetting
)
)
}

View file

@ -313,7 +313,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-home 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. </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-home 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_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>