From 7f1677a2dd2b2bf15c7532a41c5e3aa0eb2f562d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Mar=C3=A1z?= Date: Wed, 3 Aug 2022 23:58:23 +0200 Subject: [PATCH] Fix Last Notification sensor not updating when notification is repeated with the same content (#2734) Make Sensor::lastSentState and lastSentIcon nullable, set them to null when forceUpdate = true, and make null their default value everywhere. --- .../android/notifications/MessagingManager.kt | 4 +- .../sensors/NotificationSensorManager.kt | 6 +- .../31.json | 713 ++++++++++++++++++ .../android/common/sensors/SensorManager.kt | 41 +- .../common/sensors/SensorReceiverBase.kt | 4 +- .../companion/android/database/AppDatabase.kt | 3 +- .../android/database/sensor/Sensor.kt | 8 +- .../android/database/sensor/SensorDao.kt | 4 +- 8 files changed, 752 insertions(+), 31 deletions(-) create mode 100644 common/schemas/io.homeassistant.companion.android.database.AppDatabase/31.json diff --git a/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt b/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt index 3404635ad..457632aca 100644 --- a/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt @@ -750,8 +750,8 @@ class MessagingManager @Inject constructor( mainScope.launch { sensorDao.updateLastSentStateAndIcon( BluetoothSensorManager.bleTransmitter.id, - "", - "" + null, + null ) } BluetoothSensorManager().requestSensorUpdate(context) diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/NotificationSensorManager.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/NotificationSensorManager.kt index 1b863ebd3..1470f82f8 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/NotificationSensorManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/NotificationSensorManager.kt @@ -154,7 +154,8 @@ class NotificationSensorManager : NotificationListenerService(), SensorManager { lastNotification, state.toString().take(255), lastNotification.statelessIcon, - attr + attr, + forceUpdate = true, ) // Need to send update! @@ -211,7 +212,8 @@ class NotificationSensorManager : NotificationListenerService(), SensorManager { lastRemovedNotification, state.toString().take(255), lastRemovedNotification.statelessIcon, - attr + attr, + forceUpdate = true, ) // Need to send update! diff --git a/common/schemas/io.homeassistant.companion.android.database.AppDatabase/31.json b/common/schemas/io.homeassistant.companion.android.database.AppDatabase/31.json new file mode 100644 index 000000000..f4c6a34a4 --- /dev/null +++ b/common/schemas/io.homeassistant.companion.android.database.AppDatabase/31.json @@ -0,0 +1,713 @@ +{ + "formatVersion": 1, + "database": { + "version": 31, + "identityHash": "87e521cae11434d2d6208760f5e82b50", + "entities": [ + { + "tableName": "sensor_attributes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sensor_id` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `value_type` TEXT NOT NULL, PRIMARY KEY(`sensor_id`, `name`))", + "fields": [ + { + "fieldPath": "sensorId", + "columnName": "sensor_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "valueType", + "columnName": "value_type", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "sensor_id", + "name" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Authentication_List", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`host` TEXT NOT NULL, `Username` TEXT NOT NULL, `Password` TEXT NOT NULL, PRIMARY KEY(`host`))", + "fields": [ + { + "fieldPath": "host", + "columnName": "host", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "Username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "Password", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "host" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "sensors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `enabled` INTEGER NOT NULL, `registered` INTEGER DEFAULT NULL, `state` TEXT NOT NULL, `last_sent_state` TEXT DEFAULT NULL, `last_sent_icon` TEXT DEFAULT NULL, `state_type` TEXT NOT NULL, `type` TEXT NOT NULL, `icon` TEXT NOT NULL, `name` TEXT NOT NULL, `device_class` TEXT, `unit_of_measurement` TEXT, `state_class` TEXT, `entity_category` TEXT, `core_registration` TEXT, `app_registration` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "registered", + "columnName": "registered", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastSentState", + "columnName": "last_sent_state", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "lastSentIcon", + "columnName": "last_sent_icon", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "stateType", + "columnName": "state_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "deviceClass", + "columnName": "device_class", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "unitOfMeasurement", + "columnName": "unit_of_measurement", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "stateClass", + "columnName": "state_class", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "entityCategory", + "columnName": "entity_category", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "coreRegistration", + "columnName": "core_registration", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "appRegistration", + "columnName": "app_registration", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "sensor_settings", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sensor_id` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, `value_type` TEXT NOT NULL, `enabled` INTEGER NOT NULL, `entries` TEXT NOT NULL, PRIMARY KEY(`sensor_id`, `name`))", + "fields": [ + { + "fieldPath": "sensorId", + "columnName": "sensor_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "valueType", + "columnName": "value_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entries", + "columnName": "entries", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "sensor_id", + "name" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "button_widgets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `icon_id` INTEGER NOT NULL, `domain` TEXT NOT NULL, `service` TEXT NOT NULL, `service_data` TEXT NOT NULL, `label` TEXT, `background_type` TEXT NOT NULL DEFAULT 'DAYNIGHT', `text_color` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "iconId", + "columnName": "icon_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "domain", + "columnName": "domain", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "service", + "columnName": "service", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "serviceData", + "columnName": "service_data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "backgroundType", + "columnName": "background_type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'DAYNIGHT'" + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "camera_widgets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `entityId` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "mediaplayctrls_widgets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `entityId` TEXT NOT NULL, `label` TEXT, `showSkip` INTEGER NOT NULL, `showSeek` INTEGER NOT NULL, `showVolume` INTEGER NOT NULL, `showSource` INTEGER NOT NULL DEFAULT false, `background_type` TEXT NOT NULL DEFAULT 'DAYNIGHT', `text_color` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "showSkip", + "columnName": "showSkip", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showSeek", + "columnName": "showSeek", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showVolume", + "columnName": "showVolume", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "showSource", + "columnName": "showSource", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "false" + }, + { + "fieldPath": "backgroundType", + "columnName": "background_type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'DAYNIGHT'" + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "static_widget", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `entity_id` TEXT NOT NULL, `attribute_ids` TEXT, `label` TEXT, `text_size` REAL NOT NULL, `state_separator` TEXT NOT NULL, `attribute_separator` TEXT NOT NULL, `last_update` TEXT NOT NULL, `background_type` TEXT NOT NULL DEFAULT 'DAYNIGHT', `text_color` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entityId", + "columnName": "entity_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attributeIds", + "columnName": "attribute_ids", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "textSize", + "columnName": "text_size", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "stateSeparator", + "columnName": "state_separator", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attributeSeparator", + "columnName": "attribute_separator", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastUpdate", + "columnName": "last_update", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backgroundType", + "columnName": "background_type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'DAYNIGHT'" + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "template_widgets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `template` TEXT NOT NULL, `text_size` REAL NOT NULL DEFAULT 12.0, `last_update` TEXT NOT NULL, `background_type` TEXT NOT NULL DEFAULT 'DAYNIGHT', `text_color` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "template", + "columnName": "template", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "textSize", + "columnName": "text_size", + "affinity": "REAL", + "notNull": true, + "defaultValue": "12.0" + }, + { + "fieldPath": "lastUpdate", + "columnName": "last_update", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backgroundType", + "columnName": "background_type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'DAYNIGHT'" + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "notification_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `received` INTEGER NOT NULL, `message` TEXT NOT NULL, `data` TEXT NOT NULL, `source` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "received", + "columnName": "received", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "qs_tiles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `tileId` TEXT NOT NULL, `icon_id` INTEGER, `entityId` TEXT NOT NULL, `label` TEXT NOT NULL, `subtitle` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tileId", + "columnName": "tileId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "iconId", + "columnName": "icon_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "favorites", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `position` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "entityStateComplications", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `entityId` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "settings", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `websocketSetting` TEXT NOT NULL, `sensorUpdateFrequency` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "websocketSetting", + "columnName": "websocketSetting", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sensorUpdateFrequency", + "columnName": "sensorUpdateFrequency", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '87e521cae11434d2d6208760f5e82b50')" + ] + } +} \ No newline at end of file diff --git a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorManager.kt b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorManager.kt index d07ef331b..6841a288a 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorManager.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorManager.kt @@ -186,26 +186,31 @@ interface SensorManager { basicSensor: BasicSensor, state: Any, mdiIcon: String, - attributes: Map + attributes: Map, + forceUpdate: Boolean = false, ) { val sensorDao = AppDatabase.getInstance(context).sensorDao() - val sensor = sensorDao.get(basicSensor.id)?.copy( - state = state.toString(), - stateType = when (state) { - is Boolean -> "boolean" - is Int -> "int" - is Number -> "float" - is String -> "string" - else -> throw IllegalArgumentException("Unknown Sensor State Type") - }, - type = basicSensor.type, - icon = mdiIcon, - name = basicSensor.name.toString(), - deviceClass = basicSensor.deviceClass, - unitOfMeasurement = basicSensor.unitOfMeasurement, - stateClass = basicSensor.stateClass, - entityCategory = basicSensor.entityCategory - ) ?: return + val sensor = sensorDao.get(basicSensor.id)?.let { + it.copy( + state = state.toString(), + stateType = when (state) { + is Boolean -> "boolean" + is Int -> "int" + is Number -> "float" + is String -> "string" + else -> throw IllegalArgumentException("Unknown Sensor State Type") + }, + type = basicSensor.type, + icon = mdiIcon, + name = basicSensor.name.toString(), + deviceClass = basicSensor.deviceClass, + unitOfMeasurement = basicSensor.unitOfMeasurement, + stateClass = basicSensor.stateClass, + entityCategory = basicSensor.entityCategory, + lastSentState = if (forceUpdate) null else it.lastSentState, + lastSentIcon = if (forceUpdate) null else it.lastSentIcon, + ) + } ?: return sensorDao.update(sensor) sensorDao.replaceAllAttributes( diff --git a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt index 61126a26a..4de3c668d 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt @@ -297,8 +297,8 @@ abstract class SensorReceiverBase : BroadcastReceiver() { val sensor = sensorDao.get(it.uniqueId) if (sensor != null) { sensor.registered = null - sensor.lastSentState = "" - sensor.lastSentIcon = "" + sensor.lastSentState = null + sensor.lastSentIcon = null sensorDao.update(sensor) } } diff --git a/common/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt b/common/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt index 3dc3019d2..d8cdcd55c 100644 --- a/common/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt +++ b/common/src/main/java/io/homeassistant/companion/android/database/AppDatabase.kt @@ -74,7 +74,7 @@ import io.homeassistant.companion.android.common.R as commonR EntityStateComplications::class, Setting::class ], - version = 30, + version = 31, autoMigrations = [ AutoMigration(from = 24, to = 25), AutoMigration(from = 25, to = 26), @@ -82,6 +82,7 @@ import io.homeassistant.companion.android.common.R as commonR AutoMigration(from = 27, to = 28, spec = AppDatabase.Companion.Migration27to28::class), AutoMigration(from = 28, to = 29), AutoMigration(from = 29, to = 30), + AutoMigration(from = 30, to = 31), ] ) @TypeConverters( diff --git a/common/src/main/java/io/homeassistant/companion/android/database/sensor/Sensor.kt b/common/src/main/java/io/homeassistant/companion/android/database/sensor/Sensor.kt index 88b66a901..a6e46670a 100644 --- a/common/src/main/java/io/homeassistant/companion/android/database/sensor/Sensor.kt +++ b/common/src/main/java/io/homeassistant/companion/android/database/sensor/Sensor.kt @@ -15,10 +15,10 @@ data class Sensor( var registered: Boolean? = null, @ColumnInfo(name = "state") var state: String, - @ColumnInfo(name = "last_sent_state") - var lastSentState: String = "", - @ColumnInfo(name = "last_sent_icon", defaultValue = "") - var lastSentIcon: String = "", + @ColumnInfo(name = "last_sent_state", defaultValue = "NULL") + var lastSentState: String? = null, + @ColumnInfo(name = "last_sent_icon", defaultValue = "NULL") + var lastSentIcon: String? = null, @ColumnInfo(name = "state_type") var stateType: String = "", @ColumnInfo(name = "type") diff --git a/common/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt b/common/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt index e31761830..b5b395eee 100644 --- a/common/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt +++ b/common/src/main/java/io/homeassistant/companion/android/database/sensor/SensorDao.kt @@ -73,7 +73,7 @@ interface SensorDao { fun updateSettingValue(sensorId: String, settingName: String, value: String) @Query("UPDATE sensors SET last_sent_state = :state, last_sent_icon = :icon WHERE id = :sensorId") - suspend fun updateLastSentStateAndIcon(sensorId: String, state: String, icon: String) + suspend fun updateLastSentStateAndIcon(sensorId: String, state: String?, icon: String?) @Query("SELECT COUNT(id) FROM sensors WHERE enabled = 1") suspend fun getEnabledCount(): Int? @@ -85,7 +85,7 @@ interface SensorDao { async { val sensorEntity = get(sensorId) if (sensorEntity != null) { - update(sensorEntity.copy(enabled = enabled, lastSentState = "", lastSentIcon = "")) + update(sensorEntity.copy(enabled = enabled, lastSentState = null, lastSentIcon = null)) } else { add(Sensor(sensorId, enabled, state = "")) }