From 94fe0c568f42a98bc5c1a971704cec7dfab734ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pantale=C3=A3o=20Gon=C3=A7alves?= <5808343+bgoncal@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:08:11 +0100 Subject: [PATCH] Add more domains for sensors widget (#3270) ## Summary CC: @Penait1 ## Screenshots ## Link to pull request in Documentation repository Documentation: home-assistant/companion.home-assistant# ## Any other notes --- HomeAssistant.xcodeproj/project.pbxproj | 6 ++++++ .../AppIntents/Script/ScriptAppIntent.swift | 2 +- .../Sensor/IntentSensorsAppEntity.swift | 2 +- ...dgetSensorsAppIntentTimelineProvider.swift | 20 ++----------------- .../Widget/Sensor/WidgetSensorsConfig.swift | 6 ++++++ .../Cover/ControlCoverValueProvider.swift | 2 +- .../Widgets/Cover/IntentCoverEntity.swift | 2 +- .../Light/ControlLightsValueProvider.swift | 2 +- .../Widgets/Light/IntentLightEntity.swift | 2 +- .../Scene/Control/IntentSceneEntity.swift | 2 +- .../Switch/ControlSwitchValueProvider.swift | 2 +- .../Widgets/Switch/IntentSwitchEntity.swift | 2 +- .../Shared/API/Models/AppEntitiesModel.swift | 1 + Sources/Shared/ControlEntityProvider.swift | 8 ++++---- 14 files changed, 28 insertions(+), 31 deletions(-) create mode 100644 Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsConfig.swift diff --git a/HomeAssistant.xcodeproj/project.pbxproj b/HomeAssistant.xcodeproj/project.pbxproj index 13837ffdd..a4745356e 100644 --- a/HomeAssistant.xcodeproj/project.pbxproj +++ b/HomeAssistant.xcodeproj/project.pbxproj @@ -685,6 +685,8 @@ 4289DDB52C85D7B8003591C2 /* SceneAppIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4289DDB42C85D7B8003591C2 /* SceneAppIntent.swift */; }; 428CB3372CF7FC0800F1320E /* WidgetFamilySizes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 428CB3362CF7FC0800F1320E /* WidgetFamilySizes.swift */; }; 428CB3382CF7FC0800F1320E /* WidgetFamilySizes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 428CB3362CF7FC0800F1320E /* WidgetFamilySizes.swift */; }; + 428D31A52D0B33AF0025B1D7 /* WidgetSensorsConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 428D31A42D0B33AF0025B1D7 /* WidgetSensorsConfig.swift */; }; + 428D31A62D0B33AF0025B1D7 /* WidgetSensorsConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 428D31A42D0B33AF0025B1D7 /* WidgetSensorsConfig.swift */; }; 429106872BA9D22500D452F9 /* AudioRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429106862BA9D22500D452F9 /* AudioRecorder.swift */; }; 429106892BA9D5F700D452F9 /* AssistView+Build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429106882BA9D5F700D452F9 /* AssistView+Build.swift */; }; 4291068C2BA9D79500D452F9 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4291068B2BA9D79500D452F9 /* AudioPlayer.swift */; }; @@ -1995,6 +1997,7 @@ 4289DDB22C85D6B3003591C2 /* IntentSceneEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentSceneEntity.swift; sourceTree = ""; }; 4289DDB42C85D7B8003591C2 /* SceneAppIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneAppIntent.swift; sourceTree = ""; }; 428CB3362CF7FC0800F1320E /* WidgetFamilySizes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetFamilySizes.swift; sourceTree = ""; }; + 428D31A42D0B33AF0025B1D7 /* WidgetSensorsConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSensorsConfig.swift; sourceTree = ""; }; 429106862BA9D22500D452F9 /* AudioRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecorder.swift; sourceTree = ""; }; 429106882BA9D5F700D452F9 /* AssistView+Build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AssistView+Build.swift"; sourceTree = ""; }; 4291068B2BA9D79500D452F9 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; @@ -3563,6 +3566,7 @@ children = ( 3E02C0E92CA7FD2A00102131 /* WidgetSensorsAppIntent.swift */, 3E02C0EA2CA7FD2A00102131 /* WidgetSensorsAppIntentTimelineProvider.swift */, + 428D31A42D0B33AF0025B1D7 /* WidgetSensorsConfig.swift */, ); path = Sensor; sourceTree = ""; @@ -6717,6 +6721,7 @@ 42F9589F2BB4707F00497981 /* WidgetAssistView.swift in Sources */, 403AE9122C2E2BFC00D48147 /* WidgetGaugeAppIntentTimelineProvider.swift in Sources */, 42F9589C2BB4691D00497981 /* WidgetAssistProvider.swift in Sources */, + 428D31A62D0B33AF0025B1D7 /* WidgetSensorsConfig.swift in Sources */, 428CB3382CF7FC0800F1320E /* WidgetFamilySizes.swift in Sources */, 429BA2AF2C800CAB00A50996 /* SFSymbolEntity.swift in Sources */, 420461692C8F29440062E89F /* ControlLight.swift in Sources */, @@ -6988,6 +6993,7 @@ 42BA1BC92C8864C200A2FC36 /* OpenPageAppIntent.swift in Sources */, 42333ADD2D0B1771001E8408 /* EntityRegistryListForDisplay.swift in Sources */, B661FB7A226C197900E541DD /* OnboardingManualURLViewController.swift in Sources */, + 428D31A52D0B33AF0025B1D7 /* WidgetSensorsConfig.swift in Sources */, 119A827C252A3C4700D7000D /* NFCNDEFPayload+Additions.swift in Sources */, 42AC94A52CF872520050A62C /* TileCardStyleModifier.swift in Sources */, 42DD84162B14D7AC00936F16 /* WebViewExternalBusMessage.swift in Sources */, diff --git a/Sources/Extensions/AppIntents/Script/ScriptAppIntent.swift b/Sources/Extensions/AppIntents/Script/ScriptAppIntent.swift index 4af54d525..f13d84f3a 100644 --- a/Sources/Extensions/AppIntents/Script/ScriptAppIntent.swift +++ b/Sources/Extensions/AppIntents/Script/ScriptAppIntent.swift @@ -138,7 +138,7 @@ struct IntentScriptAppEntityQuery: EntityQuery, EntityStringQuery { private func getScriptEntities(matching string: String? = nil) -> [(Server, [IntentScriptEntity])] { var scriptEntities: [(Server, [IntentScriptEntity])] = [] - let entities = ControlEntityProvider(domain: .script).getEntities(matching: string) + let entities = ControlEntityProvider(domains: [.script]).getEntities(matching: string) for (server, values) in entities { scriptEntities.append((server, values.map({ entity in diff --git a/Sources/Extensions/AppIntents/Sensor/IntentSensorsAppEntity.swift b/Sources/Extensions/AppIntents/Sensor/IntentSensorsAppEntity.swift index 9d1e40666..f464cdadd 100644 --- a/Sources/Extensions/AppIntents/Sensor/IntentSensorsAppEntity.swift +++ b/Sources/Extensions/AppIntents/Sensor/IntentSensorsAppEntity.swift @@ -55,7 +55,7 @@ struct IntentSensorsAppEntityQuery: EntityQuery { private func getSensorEntities(matching string: String? = nil) -> [(Server, [IntentSensorsAppEntity])] { var sensorEntities: [(Server, [IntentSensorsAppEntity])] = [] - let entities = ControlEntityProvider(domain: .sensor).getEntities(matching: string) + let entities = ControlEntityProvider(domains: WidgetSensorsConfig.domains).getEntities(matching: string) for (server, values) in entities { sensorEntities.append((server, values.map({ entity in diff --git a/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsAppIntentTimelineProvider.swift b/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsAppIntentTimelineProvider.swift index 11e091ac7..3dae52e18 100644 --- a/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsAppIntentTimelineProvider.swift +++ b/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsAppIntentTimelineProvider.swift @@ -135,24 +135,8 @@ struct WidgetSensorsAppIntentTimelineProvider: AppIntentTimelineProvider { ) } - private func suggestions() async -> [Server: [HAAppEntity]] { - await withCheckedContinuation { continuation in - var entities: [Server: [HAAppEntity]] = [:] - for server in Current.servers.all.sorted(by: { $0.info.name < $1.info.name }) { - do { - let sensors: [HAAppEntity] = try Current.database.read { db in - try HAAppEntity - .filter(Column(DatabaseTables.AppEntity.serverId.rawValue) == server.identifier.rawValue) - .filter(Column(DatabaseTables.AppEntity.domain.rawValue) == Domain.sensor.rawValue) - .fetchAll(db) - } - entities[server] = sensors - } catch { - Current.Log.error("Failed to load sensors from database: \(error.localizedDescription)") - } - } - continuation.resume(returning: entities) - } + private func suggestions() async -> [(Server, [HAAppEntity])] { + ControlEntityProvider(domains: WidgetSensorsConfig.domains).getEntities() } } diff --git a/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsConfig.swift b/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsConfig.swift new file mode 100644 index 000000000..d42e27278 --- /dev/null +++ b/Sources/Extensions/AppIntents/Widget/Sensor/WidgetSensorsConfig.swift @@ -0,0 +1,6 @@ +import Foundation +import Shared + +enum WidgetSensorsConfig { + static var domains: [Domain] = [.sensor, .binarySensor, .inputBoolean, .person, .lock] +} diff --git a/Sources/Extensions/Widgets/Cover/ControlCoverValueProvider.swift b/Sources/Extensions/Widgets/Cover/ControlCoverValueProvider.swift index ce4b1f029..54fc889c3 100644 --- a/Sources/Extensions/Widgets/Cover/ControlCoverValueProvider.swift +++ b/Sources/Extensions/Widgets/Cover/ControlCoverValueProvider.swift @@ -10,7 +10,7 @@ struct ControlCoverValueProvider: AppIntentControlValueProvider { try await ControlRefreshDelay.wait() guard let serverId = configuration.entity?.serverId, let lightId = configuration.entity?.entityId, - let state: String = try await ControlEntityProvider(domain: .cover).currentState( + let state: String = try await ControlEntityProvider(domains: [.cover]).currentState( serverId: serverId, entityId: lightId ) else { diff --git a/Sources/Extensions/Widgets/Cover/IntentCoverEntity.swift b/Sources/Extensions/Widgets/Cover/IntentCoverEntity.swift index a09b9e298..e05a2e88c 100644 --- a/Sources/Extensions/Widgets/Cover/IntentCoverEntity.swift +++ b/Sources/Extensions/Widgets/Cover/IntentCoverEntity.swift @@ -62,7 +62,7 @@ struct IntentCoverAppEntityQuery: EntityQuery, EntityStringQuery { private func getCoverEntities(matching string: String? = nil) async -> [(Server, [IntentCoverEntity])] { var coverEntities: [(Server, [IntentCoverEntity])] = [] - let entities = ControlEntityProvider(domain: .cover).getEntities(matching: string) + let entities = ControlEntityProvider(domains: [.cover]).getEntities(matching: string) for (server, values) in entities { coverEntities.append((server, values.map({ entity in diff --git a/Sources/Extensions/Widgets/Light/ControlLightsValueProvider.swift b/Sources/Extensions/Widgets/Light/ControlLightsValueProvider.swift index 35e583823..b4e0805f3 100644 --- a/Sources/Extensions/Widgets/Light/ControlLightsValueProvider.swift +++ b/Sources/Extensions/Widgets/Light/ControlLightsValueProvider.swift @@ -20,7 +20,7 @@ struct ControlLightsValueProvider: AppIntentControlValueProvider { try await ControlRefreshDelay.wait() guard let serverId = configuration.light?.serverId, let lightId = configuration.light?.entityId, - let state: String = try await ControlEntityProvider(domain: .light).currentState( + let state: String = try await ControlEntityProvider(domains: [.light]).currentState( serverId: serverId, entityId: lightId ) else { diff --git a/Sources/Extensions/Widgets/Light/IntentLightEntity.swift b/Sources/Extensions/Widgets/Light/IntentLightEntity.swift index f671353de..7bd245727 100644 --- a/Sources/Extensions/Widgets/Light/IntentLightEntity.swift +++ b/Sources/Extensions/Widgets/Light/IntentLightEntity.swift @@ -62,7 +62,7 @@ struct IntentLightAppEntityQuery: EntityQuery, EntityStringQuery { private func getLightEntities(matching string: String? = nil) -> [(Server, [IntentLightEntity])] { var lightEntities: [(Server, [IntentLightEntity])] = [] - let entities = ControlEntityProvider(domain: .light).getEntities(matching: string) + let entities = ControlEntityProvider(domains: [.light]).getEntities(matching: string) for (server, values) in entities { lightEntities.append((server, values.map({ entity in diff --git a/Sources/Extensions/Widgets/Scene/Control/IntentSceneEntity.swift b/Sources/Extensions/Widgets/Scene/Control/IntentSceneEntity.swift index ae0dcc405..c552d5eed 100644 --- a/Sources/Extensions/Widgets/Scene/Control/IntentSceneEntity.swift +++ b/Sources/Extensions/Widgets/Scene/Control/IntentSceneEntity.swift @@ -60,7 +60,7 @@ struct IntentSceneAppEntityQuery: EntityQuery, EntityStringQuery { private func getSceneEntities(matching string: String? = nil) -> [(Server, [IntentSceneEntity])] { var sceneEntities: [(Server, [IntentSceneEntity])] = [] - let entities = ControlEntityProvider(domain: .scene).getEntities(matching: string) + let entities = ControlEntityProvider(domains: [.scene]).getEntities(matching: string) for (server, values) in entities { sceneEntities.append((server, values.map({ entity in diff --git a/Sources/Extensions/Widgets/Switch/ControlSwitchValueProvider.swift b/Sources/Extensions/Widgets/Switch/ControlSwitchValueProvider.swift index 663578e3f..2e5f93232 100644 --- a/Sources/Extensions/Widgets/Switch/ControlSwitchValueProvider.swift +++ b/Sources/Extensions/Widgets/Switch/ControlSwitchValueProvider.swift @@ -10,7 +10,7 @@ struct ControlSwitchValueProvider: AppIntentControlValueProvider { try await ControlRefreshDelay.wait() guard let serverId = configuration.entity?.serverId, let switchId = configuration.entity?.entityId, - let state = try await ControlEntityProvider(domain: .switch).currentState( + let state = try await ControlEntityProvider(domains: [.switch]).currentState( serverId: serverId, entityId: switchId ) else { diff --git a/Sources/Extensions/Widgets/Switch/IntentSwitchEntity.swift b/Sources/Extensions/Widgets/Switch/IntentSwitchEntity.swift index fccf7beeb..04226ab01 100644 --- a/Sources/Extensions/Widgets/Switch/IntentSwitchEntity.swift +++ b/Sources/Extensions/Widgets/Switch/IntentSwitchEntity.swift @@ -62,7 +62,7 @@ struct IntentSwitchAppEntityQuery: EntityQuery, EntityStringQuery { private func getSwitchEntities(matching string: String? = nil) async -> [(Server, [IntentSwitchEntity])] { var switchEntities: [(Server, [IntentSwitchEntity])] = [] - let entities = ControlEntityProvider(domain: .switch).getEntities(matching: string) + let entities = ControlEntityProvider(domains: [.switch]).getEntities(matching: string) for (server, values) in entities { switchEntities.append((server, values.map({ entity in diff --git a/Sources/Shared/API/Models/AppEntitiesModel.swift b/Sources/Shared/API/Models/AppEntitiesModel.swift index d7252a8a7..fba106abe 100644 --- a/Sources/Shared/API/Models/AppEntitiesModel.swift +++ b/Sources/Shared/API/Models/AppEntitiesModel.swift @@ -19,6 +19,7 @@ final class AppEntitiesModel: AppEntitiesModelProtocol { Domain.light, Domain.switch, Domain.sensor, + Domain.binarySensor, Domain.cover, Domain.button, Domain.inputBoolean, diff --git a/Sources/Shared/ControlEntityProvider.swift b/Sources/Shared/ControlEntityProvider.swift index 8ee0c0954..4bd0d65de 100644 --- a/Sources/Shared/ControlEntityProvider.swift +++ b/Sources/Shared/ControlEntityProvider.swift @@ -11,10 +11,10 @@ public final class ControlEntityProvider { case off } - public let domain: Domain + public let domains: [Domain] - public init(domain: Domain) { - self.domain = domain + public init(domains: [Domain]) { + self.domains = domains } public func currentState(serverId: String, entityId: String) async throws -> String? { @@ -47,7 +47,7 @@ public final class ControlEntityProvider { var entities: [HAAppEntity] = try Current.database.read { db in try HAAppEntity .filter(Column(DatabaseTables.AppEntity.serverId.rawValue) == server.identifier.rawValue) - .filter(Column(DatabaseTables.AppEntity.domain.rawValue) == domain.rawValue) + .filter(domains.map(\.rawValue).contains(Column(DatabaseTables.AppEntity.domain.rawValue))) .fetchAll(db) } if let string {