Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions OpenHABCore/Sources/OpenHABCore/Util/OpenHABItemCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,23 @@ public actor OpenHABItemCache {
}

public func getCachedItems(home: UUID) async -> [OpenHABItem]? {
// Validate home exists in storedHomes before trying to load
let storedHomes = await Preferences.shared.storedHomes
guard storedHomes[home] != nil else {
Logger.itemCache.error("Cannot get cached items: home \(home) not found in storedHomes. Available homes: \(storedHomes.keys)")
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

[nitpick] Home UUIDs and storedHomes keys are being logged without privacy settings. Since these could be considered sensitive user data, consider adding privacy modifiers to these log statements. For example:

Logger.itemCache.error("Cannot get cached items: home \(home, privacy: .private) not found in storedHomes. Available homes: \(storedHomes.keys, privacy: .private)")

Copilot uses AI. Check for mistakes.
return nil
}
await reloadCacheIfNeeded(homes: [home])
return items[home]
}

public func getCachedItem(name: String, home: UUID) async -> [OpenHABItem]? {
// Validate home exists in storedHomes before trying to load
let storedHomes = await Preferences.shared.storedHomes
guard storedHomes[home] != nil else {
Logger.itemCache.error("Cannot get cached item: home \(home) not found in storedHomes. Available homes: \(storedHomes.keys)")
return nil
}
await reloadCacheIfNeeded(homes: [home])
return items[home]?.filter { $0.name == name }
}
Expand Down Expand Up @@ -86,11 +98,17 @@ public actor OpenHABItemCache {
do {
let loadedItems = try await loadNonGroupItemsForHomes(homes)
Logger.itemCache.info("Store loaded items in cache")
homes.forEach { items[$0] = loadedItems[$0] }
// Update cache with loaded items, ensuring we don't write nil
for homeId in homes {
items[homeId] = loadedItems[homeId] ?? []
}
Comment on lines +102 to +104
Copy link
Contributor

Choose a reason for hiding this comment

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

I liked the one liner more, I think it should work with the fallback, too. But feel free to write it according to your taste.

let now = Date.now
homes.forEach { lastLoad[$0] = now }
let itemCounts = items.map { ($0.key, $0.value.count) }
Logger.itemCache.info("Loaded \(itemCounts) items to cache")
// Log only the items that were just loaded, not the entire cache
let justLoadedCounts = loadedItems.map { ($0.key, $0.value.count) }
Logger.itemCache.info("Just loaded \(justLoadedCounts) items")
let totalCacheCount = items.map { ($0.key, $0.value.count) }
Logger.itemCache.info("Total cache now contains \(totalCacheCount) items")
} catch {
Logger.itemCache.error("Could not reload \(error.localizedDescription)")
}
Expand Down Expand Up @@ -153,19 +171,34 @@ public actor OpenHABItemCache {

private func loadItems(homeId: UUID) async -> [OpenHABItem]? {
guard let networkTracker = await assureNetworkTracker(homeId: homeId) else {
Logger.itemCache.error("Home \(homeId) not reachable")
Logger.itemCache.error("Home \(homeId) not reachable - not found in storedHomes")
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

[nitpick] Home UUID is being logged without privacy settings. Since this could be considered sensitive user data, consider adding privacy modifiers. For example:

Logger.itemCache.error("Home \(homeId, privacy: .private) not reachable - not found in storedHomes")
Suggested change
Logger.itemCache.error("Home \(homeId) not reachable - not found in storedHomes")
Logger.itemCache.error("Home \(homeId, privacy: .private) not reachable - not found in storedHomes")

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure whether that new part in the log line is accurate, there may be other reasons like timeouts which cause the network tracker to be nil. Maybe you can replace the "-" with ", potentially because" or just log the failure in the assureNetworkTracker method if you don´t do that already anyway.

return nil
}
do {
let items = try await networkTracker.getStaticItems()
Logger.itemCache.info("Successfully loaded \(items.count) items for home \(homeId)")
return items
} catch {
Logger.itemCache.error("Failed to load items for home \(homeId): \(error.localizedDescription)")
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

[nitpick] Home UUID is being logged without privacy settings. Since this could be considered sensitive user data, consider adding privacy modifiers. For example:

Logger.itemCache.error("Failed to load items for home \(homeId, privacy: .private): \(error.localizedDescription)")
Suggested change
Logger.itemCache.error("Failed to load items for home \(homeId): \(error.localizedDescription)")
Logger.itemCache.error("Failed to load items for home \(homeId, privacy: .private): \(error.localizedDescription)")

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +182
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of the verbose do-catch syntax we can do a guard let items = try?... here with log and return in the else branch?

return nil
}
return try? await networkTracker.getStaticItems()
}

private func assureNetworkTracker(homeId: UUID) async -> NetworkTracker? {
if networkTrackers[homeId] == nil, let homePreferences = await Preferences.shared.storedHomes[homeId] {
if networkTrackers[homeId] == nil {
guard let homePreferences = await Preferences.shared.storedHomes[homeId] else {
Logger.itemCache.error("Home \(homeId) not found in storedHomes")
return nil
}
Logger.itemCache.info("Creating network tracker for home \(homeId)")
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

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

[nitpick] Home UUIDs are being logged without privacy settings. Since these could be considered sensitive user data, consider adding privacy modifiers. For example:

Logger.itemCache.info("Creating network tracker for home \(homeId, privacy: .private)")

Copilot uses AI. Check for mistakes.
Logger.itemCache.info("Local: \(homePreferences.localConnectionConfig.url), Remote: \(homePreferences.remoteConnectionConfig.url)")
let tracker = NetworkTracker(timeout: OpenHABItemCache.networkTimeout)
networkTrackers[homeId] = tracker
await tracker.startTracking(connectionConfigurations: [homePreferences.localConnectionConfig, homePreferences.remoteConnectionConfig])
Logger.itemCache.info("Network tracker started for home \(homeId)")
} else {
Logger.itemCache.info("Using existing network tracker for home \(homeId)")
}
// TODO: do we need to make sure / wait that the connection is live?
return networkTrackers[homeId]
}
}
Expand Down
2 changes: 1 addition & 1 deletion OpenHABCore/Sources/OpenHABCore/Util/Preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public actor Preferences {

@MainActor
public extension Preferences {
func listStoredHomes() -> [UUID] {
func listStoredHomes() async -> [UUID] {
let preferenceIds = storedHomes
.sorted { e1, e2 in
e1.value.homeName <= e2.value.homeName
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion openHAB/HomeSelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ struct HomeSelectionView: View {
}

private func loadHomesList() {
homes = Preferences.shared.listStoredHomes()
Task { @MainActor in
homes = await Preferences.shared.listStoredHomes()
}
}

private func delete(home toDelete: UUID?) {
Expand Down
Loading