Skip to content

Implement SensorRepository on top of SensorDao to handle default#7040

Open
TimoPtr wants to merge 3 commits into
feature/basic_sensors_injectionfrom
feature/sensorRepository
Open

Implement SensorRepository on top of SensorDao to handle default#7040
TimoPtr wants to merge 3 commits into
feature/basic_sensors_injectionfrom
feature/sensorRepository

Conversation

@TimoPtr

@TimoPtr TimoPtr commented Jun 17, 2026

Copy link
Copy Markdown
Member

Summary

This PR wrap the access of to the SensorDao into the SensorRepository. The repository has a new logic that make sure that we always have all the sensors return even if they are not yet in the DAO because they don't need to be there at the moment. It uses the Set<BasicSensor> as source of truth.

Fix #7025

Checklist

  • New or updated tests have been added to cover the changes following the testing guidelines.
  • The code follows the project's code style and best_practices.
  • The changes have been thoroughly tested, and edge cases have been considered.
  • Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Any other notes

Based on #7031

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a real SensorRepository abstraction backed by SensorDao, using the generated BasicSensor catalog as the source of truth to synthesize default sensor rows when no DB row exists. This addresses cases like #7025 where sensors (e.g., last_update) can be missing from “Manage sensors” due to the DB not being pre-populated.

Changes:

  • Implement SensorRepository as an interface + SensorRepositoryImpl (catalog-aware defaults, DAO delegation, cleanup helpers)
  • Migrate app + wear call sites from SensorDao direct access to SensorRepository (including entry points and device commands)
  • Update SensorDao to use @Upsert, remove legacy “create-if-missing” helpers, and add/adjust unit tests

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
wear/src/main/kotlin/io/homeassistant/companion/android/sensors/HealthServicesSensorManager.kt Switch sensor reads/writes from DAO accessor to repository accessor
wear/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt Inject SensorRepository and pass it to BLE device command handling
wear/src/main/kotlin/io/homeassistant/companion/android/home/MainViewModel.kt Use repository flow + enable/disable operations via repository
common/src/test/kotlin/io/homeassistant/companion/android/sensors/SensorManagerTest.kt Update entry point mocking from DAO to repository
common/src/test/kotlin/io/homeassistant/companion/android/common/sensors/SensorRepositoryImplTest.kt New unit tests for defaulting/merging behavior in repository
common/src/test/kotlin/io/homeassistant/companion/android/common/sensors/AudioSensorManagerTest.kt Migrate tests from DAO expectations to repository expectations
common/src/test/kotlin/io/homeassistant/companion/android/common/data/servers/ServerManagerImplTest.kt Replace DAO dependency with repository dependency in server removal tests
common/src/main/kotlin/io/homeassistant/companion/android/database/sensor/SensorDao.kt Make DAO internal, replace update with @Upsert, remove old helper logic
common/src/main/kotlin/io/homeassistant/companion/android/database/DatabaseEntryPoint.kt Entry point now exposes SensorRepository (not SensorDao)
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorWorkerBase.kt Use repository for enabled-count and orphan cleanup
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorRepositoryImpl.kt New implementation: catalog-aware defaults + DAO delegation
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorRepository.kt Replace stub class with full repository interface contract
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt Use repository for settings/state/full reads + enabled-count check
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorModule.kt New Hilt binding module for SensorRepository
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/SensorManager.kt Route “enabled” checks and updates through repository
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/NextAlarmManager.kt Use repository for sensor settings reads/writes
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/NetworkSensorManager.kt Use repository for sensor settings reads/writes
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/LastUpdateManager.kt Use repository for intent settings maintenance
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/LastRebootSensorManager.kt Use repository for full sensor + settings access
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/BluetoothSensorManager.kt Use repository via entry point and sensor manager accessor
common/src/main/kotlin/io/homeassistant/companion/android/common/sensors/AudioSensorManager.kt Use repository for full sensor reads
common/src/main/kotlin/io/homeassistant/companion/android/common/notifications/DeviceCommands.kt Device command now updates sensor settings/state via repository
common/src/main/kotlin/io/homeassistant/companion/android/common/data/servers/ServerManagerImpl.kt Delete-server path now delegates sensor cleanup to repository
common/src/main/kotlin/io/homeassistant/companion/android/common/data/servers/ServerConnectionStateProviderImpl.kt Restrict implementation visibility to internal
app/src/test/kotlin/io/homeassistant/companion/android/sensors/SensorRepositoryTest.kt Update injection expectations for repository + catalog multibinding
app/src/test/kotlin/io/homeassistant/companion/android/onboarding/locationsharing/LocationSharingViewModelTest.kt Update tests to mock repository instead of DAO
app/src/main/kotlin/io/homeassistant/companion/android/settings/sensor/SensorSettingsViewModel.kt Collect sensors via repository flow
app/src/main/kotlin/io/homeassistant/companion/android/settings/sensor/SensorDetailViewModel.kt Use repository for settings/full/state updates
app/src/main/kotlin/io/homeassistant/companion/android/sensors/GeocodeSensorManager.kt Use repository for settings reads/writes
app/src/main/kotlin/io/homeassistant/companion/android/onboarding/locationsharing/LocationSharingViewModel.kt Use repository for enabling location sensors
app/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt Inject repository and pass it to BLE device commands
app/src/main/kotlin/io/homeassistant/companion/android/HomeAssistantApplication.kt Use repository for last_update intent registration settings
app/src/full/kotlin/io/homeassistant/companion/android/sensors/LocationSensorManager.kt Use repository via entry point + sensor manager accessor for settings/attributes

Comment on lines 197 to 202
try {
serverManager.servers().map { server ->
ioScope.async { syncSensorsWithServer(context, serverManager, server, sensorDao) }
ioScope.async { syncSensorsWithServer(context, serverManager, server, sensorRepository) }
}.awaitAll()
Timber.i("Sensor updates and sync completed")
} catch (e: Exception) {
Comment on lines 227 to 229
val coreSensorStatus: Map<String, Boolean>? =
if (supportsDisabledSensors && (serverIsTrusted || (sensorDao.getEnabledCount() ?: 0) > 0)) {
if (supportsDisabledSensors && (serverIsTrusted || sensorRepository.getEnabledCount() > 0)) {
config.entities
Comment on lines +51 to +55
// Catalog-aware: a default-enabled sensor counts even before it has a stored row, so this is the
// count of effective-enabled (sensor, server) pairs, not just persisted enabled rows.
override suspend fun getEnabledCount(): Int =
configuredServerIds().sumOf { serverId -> getAllServer(serverId).count { it.enabled } }

Comment on lines +68 to +76
var throwableCaptured: Throwable? = null
FailFast.setHandler { throwable, _ -> throwableCaptured = throwable }

val result = repository.get("unknown", 1)

// No backing BasicSensor means the sensor doesn't exist: FailFast fires and the read is null.
assertNotNull(throwableCaptured)
assertNull(result)
}

/**
* Single access point for sensor state and the sensor catalog.
* Single access point to sensors their state, settings and attributes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Last Update Sensor missing with google play system update 1 May 2026

2 participants