diff --git a/app/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt b/app/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt index 9c62d5bc4..2def0321c 100644 --- a/app/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt +++ b/app/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt @@ -14,6 +14,7 @@ import io.homeassistant.companion.android.database.authentication.Authentication import io.homeassistant.companion.android.database.sensor.Attribute import io.homeassistant.companion.android.database.sensor.Sensor import io.homeassistant.companion.android.database.sensor.SensorDao +import io.homeassistant.companion.android.database.sensor.Setting import io.homeassistant.companion.android.database.widget.ButtonWidgetDao import io.homeassistant.companion.android.database.widget.ButtonWidgetEntity import io.homeassistant.companion.android.database.widget.StaticWidgetDao @@ -26,11 +27,12 @@ import io.homeassistant.companion.android.database.widget.TemplateWidgetEntity Attribute::class, Authentication::class, Sensor::class, + Setting::class, ButtonWidgetEntity::class, StaticWidgetEntity::class, TemplateWidgetEntity::class ], - version = 10 + version = 11 ) abstract class AppDatabase : RoomDatabase() { abstract fun authenticationDao(): AuthenticationDao @@ -65,7 +67,8 @@ abstract class AppDatabase : RoomDatabase() { MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, - MIGRATION_9_10 + MIGRATION_9_10, + MIGRATION_10_11 ) .build() } @@ -194,5 +197,11 @@ abstract class AppDatabase : RoomDatabase() { } } } + + private val MIGRATION_10_11 = object : Migration(10, 11) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("CREATE TABLE IF NOT EXISTS `sensor_settings` (`sensor_id` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `value_type` TEXT NOT NULL DEFAULT 'string', PRIMARY KEY(`sensor_id`, `name`))") + } + } } } diff --git a/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt b/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt index bf1663c82..51891fe51 100644 --- a/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt +++ b/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt @@ -17,12 +17,22 @@ interface SensorDao { @Query("SELECT * FROM Sensors WHERE id = :id") fun getFull(id: String): SensorWithAttributes? + @Transaction + @Query("SELECT * FROM sensor_settings WHERE sensor_id = :id") + fun getSettings(id: String): List + @Insert(onConflict = OnConflictStrategy.IGNORE) fun add(sensor: Sensor) @Insert(onConflict = OnConflictStrategy.REPLACE) fun add(attribute: Attribute) + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun add(setting: Setting) + + @Query("DELETE FROM sensor_settings WHERE sensor_id = :sensorId AND name = :settingName") + fun removeSetting(sensorId: String, settingName: String) + @Update fun update(sensor: Sensor) diff --git a/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorWithSettings.kt b/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorWithSettings.kt new file mode 100644 index 000000000..754c6947e --- /dev/null +++ b/app/src/main/java/io/homeassistant/companion/android/database/sensor/SensorWithSettings.kt @@ -0,0 +1,14 @@ +package io.homeassistant.companion.android.database.sensor + +import androidx.room.Embedded +import androidx.room.Relation + +data class SensorWithSettings( + @Embedded + val sensor: Sensor, + @Relation( + parentColumn = "id", + entityColumn = "sensor_id" + ) + val settings: List +) diff --git a/app/src/main/java/io/homeassistant/companion/android/database/sensor/Setting.kt b/app/src/main/java/io/homeassistant/companion/android/database/sensor/Setting.kt new file mode 100644 index 000000000..2f9d5c8c7 --- /dev/null +++ b/app/src/main/java/io/homeassistant/companion/android/database/sensor/Setting.kt @@ -0,0 +1,16 @@ +package io.homeassistant.companion.android.database.sensor + +import androidx.room.ColumnInfo +import androidx.room.Entity + +@Entity(tableName = "sensor_settings", primaryKeys = ["sensor_id", "name"]) +data class Setting( + @ColumnInfo(name = "sensor_id") + val sensorId: String, + @ColumnInfo(name = "name") + val name: String, + @ColumnInfo(name = "value") + var value: String, + @ColumnInfo(name = "value_type") + var valueType: String +) diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/NetworkSensorManager.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/NetworkSensorManager.kt index 7e1e97612..ed4e5ba48 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/NetworkSensorManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/NetworkSensorManager.kt @@ -7,6 +7,8 @@ import android.net.wifi.WifiManager import android.os.Build import android.util.Log import io.homeassistant.companion.android.R +import io.homeassistant.companion.android.database.AppDatabase +import io.homeassistant.companion.android.database.sensor.Setting import okhttp3.Call import okhttp3.Callback import okhttp3.OkHttpClient @@ -70,6 +72,7 @@ class NetworkSensorManager : SensorManager { R.string.basic_sensor_name_public_ip, R.string.sensor_description_public_ip ) + private const val GET_CURRENT_BSSID = "get_current_bssid" } override val enabledByDefault: Boolean @@ -174,7 +177,27 @@ class NetworkSensorManager : SensorManager { conInfo = wifiManager.connectionInfo } - val bssid = if (conInfo!!.bssid == null) "" else conInfo.bssid + var bssid = if (conInfo!!.bssid == null) "" else conInfo.bssid + + val settingName = "replace_$bssid" + val sensorDao = AppDatabase.getInstance(context).sensorDao() + val sensorSettings = sensorDao.getSettings(bssidState.id) + val getCurrentBSSID = sensorSettings?.firstOrNull { it.name == GET_CURRENT_BSSID }?.value ?: "false" + val currentSetting = sensorSettings?.firstOrNull { it.name == settingName }?.value ?: "" + if (getCurrentBSSID == "true") { + if (currentSetting == "") { + sensorDao.add(Setting(bssidState.id, GET_CURRENT_BSSID, "false", "toggle")) + sensorDao.add(Setting(bssidState.id, settingName, bssid, "string")) + } + } else { + if (currentSetting != "") + bssid = currentSetting + else + sensorDao.removeSetting(bssidState.id, settingName) + + sensorDao.add(Setting(bssidState.id, GET_CURRENT_BSSID, "false", "toggle")) + } + val icon = if (bssid != "") "mdi:wifi" else "mdi:wifi-off" onSensorUpdated( context, diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorDetailFragment.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorDetailFragment.kt index ba022ae1f..bdece3a90 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorDetailFragment.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorDetailFragment.kt @@ -3,6 +3,8 @@ package io.homeassistant.companion.android.sensors import android.content.pm.PackageManager import android.os.Bundle import android.os.Handler +import android.text.InputType +import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat @@ -13,6 +15,7 @@ import io.homeassistant.companion.android.common.dagger.GraphComponentAccessor import io.homeassistant.companion.android.database.AppDatabase import io.homeassistant.companion.android.database.sensor.Sensor import io.homeassistant.companion.android.database.sensor.SensorDao +import io.homeassistant.companion.android.database.sensor.Setting class SensorDetailFragment( private val sensorManager: SensorManager, @@ -92,6 +95,7 @@ class SensorDetailFragment( val sensorDao = AppDatabase.getInstance(requireContext()).sensorDao() val fullData = sensorDao.getFull(basicSensor.id) + val sensorSettings = sensorDao.getSettings(basicSensor.id) if (fullData?.sensor == null) return val sensorData = fullData.sensor @@ -147,6 +151,57 @@ class SensorDetailFragment( } else it.isVisible = false } + + findPreference("sensor_settings")?.let { + if (sensorData.enabled && !sensorSettings.isNullOrEmpty()) { + sensorSettings.forEach { setting -> + val key = "setting_${setting.name}" + if (setting.valueType == "toggle") { + val pref = findPreference(key) ?: SwitchPreference(requireContext()) + pref.key = key + pref.title = setting.name + pref.isChecked = setting.value == "true" + pref.isIconSpaceReserved = false + pref.setOnPreferenceChangeListener { _, newState -> + val isEnabled = newState as Boolean + + sensorDao.add(Setting(basicSensor.id, setting.name, isEnabled.toString(), "toggle")) + return@setOnPreferenceChangeListener true + } + if (!it.contains(pref)) + it.addPreference(pref) + } else if (setting.valueType == "string" || setting.valueType == "number") { + val pref = findPreference(key) ?: EditTextPreference(requireContext()) + pref.key = key + pref.title = setting.name + if (setting.value != "") + pref.summary = setting.value + else + pref.summary = pref.text + pref.isIconSpaceReserved = false + + pref.setOnBindEditTextListener { fieldType -> + if (setting.valueType == "number") + fieldType.inputType = InputType.TYPE_CLASS_NUMBER + } + + if (pref.text != null) + sensorDao.add( + Setting( + basicSensor.id, + setting.name, + pref.text, + setting.valueType + ) + ) + if (!it.contains(pref)) + it.addPreference(pref) + } + } + it.isVisible = true + } else + it.isVisible = false + } } private fun updateSensorEntity( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa2660775..84f18cb48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,7 +208,7 @@ like to connect to: Volume level for calls on the device Volume level for music on the device Volume level for the ringer on the device - The mac address of the currently connected WiFi access point + The mac address of the currently connected WiFi access point. Enabling the "get_current_bssid" toggle will create a new setting allowing you to rename the state sent back to Home Assistant for the chosen mac address. The toggle will default to off after the current BSSID is stored, so you will need to enable it once for each BSSID you wish to rename. You can also clear out the value to remove the setting in the next update. The name of the network the device is currently connected to The frequency band of the connected network The current IP address of the device on the network @@ -242,6 +242,7 @@ like to connect to: Volume Level Call Volume Level Music Volume Level Ringer + Sensor Settings Use this to manage what sensors are enabled/disabled. Manage Sensors Sensors diff --git a/app/src/main/res/xml/sensor_detail.xml b/app/src/main/res/xml/sensor_detail.xml index 0ab9427b6..eb179b64b 100644 --- a/app/src/main/res/xml/sensor_detail.xml +++ b/app/src/main/res/xml/sensor_detail.xml @@ -36,4 +36,9 @@ app:key="attributes" app:title="@string/attributes" app:iconSpaceReserved="false"/> + + \ No newline at end of file