Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
a092c56
openHABWidget: add interactive switch and sensor widgets
timbms May 28, 2026
6b54a39
Merge branch 'develop' into feature/widgets-with-item-display
timbms May 28, 2026
687d341
ItemEventStream: backport SSE watchdog and self-contained network mon…
timbms May 28, 2026
365ddb0
Upgrade SwiftFormatPlugin 0.58.7→0.61.1, SwiftLintPlugin 0.62.2→0.63.…
timbms May 28, 2026
aa6faf5
Add AppShortcutsProvider and fix intent dialog gaps
timbms May 19, 2026
94a59e5
Fix AppIntentsMetadataProcessor synonym warnings in AppEnum cases
timbms May 27, 2026
317a4b4
Convert AppShortcuts.strings to AppShortcuts.xcstrings String Catalog
timbms May 27, 2026
77d579e
Bump deployment targets to iOS 17.0 / watchOS 10.0
timbms May 27, 2026
c0ed231
Linting and AppIntents SSE warnings fixes
timbms May 28, 2026
cf9145b
Register SetActiveHomeIntent with AppShortcutsProvider
timbms May 28, 2026
4824a8f
Replace SetLocationValueIntent with SetActiveHomeIntent in AppShortcu…
timbms May 28, 2026
6a709ef
Use iOS 17 animation and scroll APIs
timbms May 31, 2026
088b106
Use iOS 18 onScrollGeometryChange in SitemapPageView
timbms May 31, 2026
3cf2d07
Bump minimum deployment targets to iOS 18 / watchOS 11
timbms Jun 1, 2026
c73f2ec
Make ScrollToTop overlay button conditional (#1231)
DigiH Jun 1, 2026
ad3244a
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jun 1, 2026
c7ab95e
Sensor widget: support 1/2/4 items per small/medium/large size
timbms Jun 1, 2026
984b82c
Sensor widget: format state values using stateDescription numberPattern
timbms Jun 1, 2026
89c3ac9
Merge develop + fix build warnings; add iOS home screen widgets with …
timbms Jun 12, 2026
b40a830
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jun 12, 2026
7b02c7f
chore: bump openHABTestsSwift deployment target to iOS 18.0
timbms Jun 12, 2026
cb183ec
build: raise macOS minimum to 15 for AsyncSequence.Failure support
timbms Jun 14, 2026
b389891
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jun 14, 2026
208e4b7
chore: add shared schemes for openHABWidgetExtension and OpenHABWatch…
timbms Jun 14, 2026
c87f69d
fix: restore project.pbxproj corrupted by bad 3-way merge of pbxproj
timbms Jun 14, 2026
07e4145
chore: update openHABWidgetExtension scheme with askForAppToLaunch
timbms Jun 14, 2026
c508e9b
Merge remote-tracking branch 'origin/develop' into feature/widgets-wi…
timbms Jun 15, 2026
b7e7f6a
Merge develop into feature/widgets-with-item-display
timbms Jun 17, 2026
099ece9
Merge origin/develop into feature/widgets-with-item-display
timbms Jun 17, 2026
62fcf0c
l10n: translate 2 new widget keys into all 9 languages
timbms Jun 17, 2026
c679848
l10n: add Spanish, Finnish, Norwegian, and Russian translations
timbms Jun 17, 2026
d811179
chore: remove 5 stale localization keys on feature branch
timbms Jun 17, 2026
b64402b
l10n: switch German and French translations to informal address (du/tu)
timbms Jun 17, 2026
3fddb18
l10n: add Spanish, Finnish, Norwegian, and Russian translations
timbms Jun 17, 2026
7238049
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jun 24, 2026
f87c54e
Merge branch 'l10n/es-fi-nb-ru-translations' into feature/widgets-wit…
timbms Jun 24, 2026
3d384cc
fix: add provisioning profile for openHABWidgetExtension
timbms Jun 24, 2026
19c6810
committed version bump: 3.4.1 (287)
Jun 24, 2026
7980fe7
Merge branch 'app-intents-shortcuts-and-dialog-fixes' into feature/wi…
timbms Jun 24, 2026
f8aa266
Merge remote-tracking branch 'origin/feature/widgets-with-item-displa…
timbms Jun 24, 2026
85c6698
fix: add OpenHABShortcuts.swift to app target to resolve AppShortcuts…
timbms Jun 25, 2026
7f0bc02
fix: notification ping now respects the ringer/silent switch (#1278)
timbms Jul 1, 2026
38ecdd4
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jul 1, 2026
039506b
fix: lock screen widgets now send commands on tap
timbms Jul 1, 2026
4c6a233
Widget adjustments (#1279)
DigiH Jul 1, 2026
cc44c22
fix: animate GIFs in the Image sitemap widget (#1280)
timbms Jul 1, 2026
6b49872
committed version bump: 3.4.2 (290)
Jul 1, 2026
08cb541
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jul 2, 2026
8f8e655
fix: detect GIF images by magic bytes in ImageRowView
timbms Jul 2, 2026
487df89
chore: apply linter fixes
timbms Jul 2, 2026
3170496
feat: make Dimmer items selectable in Set Switch State intent
timbms Jul 2, 2026
bd909d8
fix: sync allowedItemTypes with query and add regression test
timbms Jul 2, 2026
84fa043
committed version bump: 3.4.3 (292)
Jul 2, 2026
68c17d7
committed version bump: 3.4.4 (293)
Jul 2, 2026
99d941d
Fix small widget content to be cntered
DigiH Jul 2, 2026
9ee5afa
committed version bump: 3.4.5 (294)
Jul 2, 2026
1c93a19
refactor: remove UIImageView polling timer from MJPEG video stream
timbms Jul 3, 2026
fb5de80
feat: wide-display sitemap grid and full-width media rows
timbms Jul 3, 2026
5a3cc5f
feat: add accessory widget previews for Switch and Sensor widgets
timbms Jul 3, 2026
4aed355
chore: apply linter fixes
timbms Jul 3, 2026
061b4af
chore: merge develop into feature/widgets-with-item-display
timbms Jul 3, 2026
56c9fa8
Allow for two lines label and value for iOS Lock Screen Accessories (…
DigiH Jul 3, 2026
452a564
committed version bump: 3.4.6 (296)
Jul 4, 2026
000af35
fix: remove duplicate knownRegions from project.pbxproj
timbms Jul 6, 2026
19df9dd
fix: add Localizable.xcstrings to widget extension target membership
timbms Jul 6, 2026
c1b535c
fix: show message body below title in notification list
timbms Jul 6, 2026
c98545c
Small Widget background watermark alignment adjustments (#1289)
DigiH Jul 6, 2026
a41cd1d
Migrate sitemap page updates from long-polling to SSE (#1168)
timbms Jul 6, 2026
28455e2
feat: add CarPlay support with sitemap-based favorites scene
timbms Jul 4, 2026
9aa4791
refactor: migrate CarPlay streaming from long-poll to SSE
timbms Jul 5, 2026
6afb57d
fix: show placeholder instead of empty CPListTemplate when no compati…
timbms Jul 5, 2026
3a295d1
feat: switch CarPlay to CPGridTemplate with openHAB icons
timbms Jul 5, 2026
d0095c5
refactor: replace remote icon fetch with SF symbol mapping in CarPlay
timbms Jul 6, 2026
bcf991b
committed version bump: 3.4.7 (297)
Jul 6, 2026
669773d
Make Circular Accessory Switch icon state aware (#1291)
DigiH Jul 6, 2026
034e4cb
fix: remove stale %lld %% localization keys for screensaver percentag…
timbms Jul 6, 2026
6529c4e
fix: remove 7 stale localization keys with no source references
timbms Jul 6, 2026
9bde87e
Merge branch 'feature/wide-display-sitemap-grid' into feature/widgets…
timbms Jul 6, 2026
3d06c9a
committed version bump: 3.4.8 (298)
Jul 6, 2026
08e93eb
Widgets layout adjustments (#1292)
DigiH Jul 7, 2026
c3a6405
fix: improve CarPlay robustness and localizations
timbms Jul 7, 2026
62ef000
fix: use LocalizedStringResource in AppIntents display representations
timbms Jul 7, 2026
5fce976
chore: switch main app target to CarPlay entitlements file
timbms Jul 8, 2026
c2fe5f5
refactor: rename OpenHABIconOverlay to OpenHABIconWatermark and compl…
timbms Jul 8, 2026
b20cfcd
Merge branch 'feature/carplay-sse' into feature/widgets-with-item-dis…
timbms Jul 9, 2026
3d0747e
fix: complete missing localizations for 3 strings
timbms Jul 9, 2026
3facccd
committed version bump: 3.4.9 (300)
Jul 9, 2026
796b65d
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jul 12, 2026
7d57f63
fix: keep SSE stream alive across CarPlay page refreshes
timbms Jul 12, 2026
1224651
Minor widget layout adjustments
DigiH Jul 12, 2026
4c981ed
fix: show inline error for inaccessible images and suppress connectiv…
timbms Jul 12, 2026
9d8f91c
Merge remote-tracking branch 'origin/develop' into feature/widgets-wi…
timbms Jul 13, 2026
e9e4680
committed version bump: 3.4.10 (302)
Jul 15, 2026
0ee8452
singleMappingButton toggle button fix (#1296)
DigiH Jul 15, 2026
b8dde57
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jul 15, 2026
1339144
docs: expand ohMinimumHitTarget doc comment
timbms Jul 15, 2026
c42077e
Remove ohMinimumHitTarget() to reinstate consistent sitemap row heigh…
DigiH Jul 15, 2026
00267e7
committed version bump: 3.4.11 (303)
Jul 15, 2026
08e8eae
Merge branch 'develop' into feature/widgets-with-item-display
timbms Jul 15, 2026
90bf013
Merge remote-tracking branch 'origin/develop' into feature/widgets-wi…
timbms Jul 16, 2026
e331753
SensorItemRow adjustments for consistent value font sizes (#1300)
DigiH Jul 17, 2026
743ca5e
fix: use CPInformationTemplate for CarPlay not-configured placeholder
timbms Jul 18, 2026
63a55b8
fix: widget visibility filtering and test-layer crash fixes
timbms Jul 18, 2026
48a8905
committed version bump: 3.4.12 (306)
Jul 18, 2026
3c198b9
feat(carplay): restrict widgets to plain switches and press-release b…
timbms Jul 19, 2026
e75214d
committed version bump: 3.4.13 (307)
Jul 19, 2026
c782746
Extend CarPlay icons (#1302)
DigiH Jul 19, 2026
40abeac
CarPlay placeholder text adjustments (#1303)
DigiH Jul 20, 2026
dbf9282
committed version bump: 3.4.14 (308)
Jul 20, 2026
b73c3e1
Add Garage Door icon to CarPlay icons (#1304)
DigiH Jul 20, 2026
337cac5
l10n: translate and review CarPlay strings for all supported languages
timbms Jul 20, 2026
a947995
committed version bump: 3.4.15 (309)
Jul 20, 2026
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
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
- UI tests: `xcodebuild test -workspace openHAB.xcworkspace -scheme openHABUITests`

## Architecture
- **Main app**: openHAB/ - UIKit + SwiftUI hybrid iOS app targeting iOS 16+
- **Main app**: openHAB/ - UIKit + SwiftUI hybrid iOS app targeting iOS 18+
- **Core library**: OpenHABCore/ - Swift Package with shared business logic, models, API clients
- **Watch app**: openHABWatch/ - watchOS companion app (watchOS 10+)
- **Watch app**: openHABWatch/ - watchOS companion app (watchOS 11+)
- **Extensions**: openHABIntents/ (Siri shortcuts), NotificationService/ (rich notifications)
- **Tests**: openHABTestsSwift/ (Swift Testing), openHABUITests/ (UI automation). For targeted bug fixes, run only focused tests by default.
- **Dependencies**: Kingfisher (image loading), SwiftUI, Firebase, OpenAPI runtime, SFSafeSymbols
Expand Down
6 changes: 2 additions & 4 deletions AppIntents/ContactState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@
import AppIntents
import Foundation

@available(iOS 17.0, macOS 14.0, *)
enum ContactState: String, AppEnum {
case open = "OPEN"
case closed = "CLOSED"

static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Contact State")

static let caseDisplayRepresentations: [Self: DisplayRepresentation] = [
.open: "Open",
.closed: "Closed"
.open: DisplayRepresentation(title: "Open", synonyms: ["Opened", "Triggered", "Active"]),
.closed: DisplayRepresentation(title: "Closed", synonyms: ["Shut", "Inactive", "Reset"])
]
}

@available(iOS 17.0, macOS 14.0, *)
extension ContactState: CustomLocalizedStringResourceConvertible {
var localizedStringResource: LocalizedStringResource {
switch self {
Expand Down
6 changes: 4 additions & 2 deletions AppIntents/Home.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ enum HomeResolver {
)
}

/// Production overload for item-by-name resolution (iOS 16 compat intents).
/// Production overload for item-by-name resolution.
/// Builds a stable-identifier-aware `findHomeId` closure and delegates to the testable overload.
static func resolveHomeId(selectedHome: Home?,
itemName: String,
Expand Down Expand Up @@ -219,7 +219,9 @@ struct Home: AppEntity {
}
}

static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Home")
static let typeDisplayRepresentation = TypeDisplayRepresentation(
name: LocalizedStringResource("Home", defaultValue: "Home")
)

static let defaultQuery = HomeQuery()

Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/ContactStateIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum ContactStateError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct ContactStateIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
3 changes: 1 addition & 2 deletions AppIntents/Intents/GetItemStateIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ enum ItemStateError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct GetItemStateIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand All @@ -69,7 +68,7 @@ struct GetItemStateIntent: AppIntent {
}

static let title: LocalizedStringResource = "Get Item State"
static let description = IntentDescription("Retrieve the current state of an item")
static let description = IntentDescription("Retrieve the current state of an item", resultValueName: "State")

@Parameter(title: "Home")
var home: Home?
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetActiveHomeIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import AppIntents
import OpenHABCore

@available(iOS 17.0, macOS 14.0, watchOS 10.0, *)
struct SetActiveHomeIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetColorValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ enum ColorValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetColorValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetDateTimeValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum DateTimeValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetDateTimeValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetDimmerRollerValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ enum DimmerRollerValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetDimmerRollerValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetLocationValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ enum LocationValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetLocationValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
1 change: 0 additions & 1 deletion AppIntents/Intents/SetNumberValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum NumberValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetNumberValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
3 changes: 1 addition & 2 deletions AppIntents/Intents/SetPlayerValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum PlayerValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetPlayerValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down Expand Up @@ -77,6 +76,6 @@ struct SetPlayerValueIntent: AppIntent {
throw PlayerValueError.commandFailed(error.localizedDescription)
}

return .result(dialog: "Sent \(action) to \(itemEntity.label)")
return .result(dialog: "Sent \(action.rawValue) to \(itemEntity.label)")
}
}
1 change: 0 additions & 1 deletion AppIntents/Intents/SetStringValueIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ enum StringValueError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetStringValueIntent: AppIntent {
static var openAppWhenRun: Bool {
false
Expand Down
11 changes: 8 additions & 3 deletions AppIntents/Intents/SetSwitchItemIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ enum ControlItemError: Error, CustomLocalizedStringResourceConvertible {
}
}

@available(iOS 17.0, macOS 14.0, *)
struct SetSwitchItemIntent: AppIntent {
static var openAppWhenRun: Bool {
false
}

static var allowedItemTypes: [OpenHABItem.ItemType] {
[.switchItem]
[.switchItem, .dimmer]
}

static var parameterSummary: some ParameterSummary {
Expand Down Expand Up @@ -78,6 +77,12 @@ struct SetSwitchItemIntent: AppIntent {
throw ControlItemError.commandFailed(error.localizedDescription)
}

return .result(dialog: "Sent \(action) to \(itemEntity.label)")
// openHAB accepts commands asynchronously: it returns HTTP 200 before the item
// state has actually changed. Without a pause, WidgetKit's immediate timeline
// refresh races the server and fetches the pre-command state, overwriting the
// Toggle's optimistic visual flip and showing the wrong colour/text.
try? await Task.sleep(for: .milliseconds(600))

return .result(dialog: "Sent \(action.rawValue) to \(itemEntity.label)")
}
}
14 changes: 4 additions & 10 deletions AppIntents/ItemEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import OpenHABCore

// MARK: - Shared Protocol for All Item Entities

@available(iOS 17.0, macOS 14.0, *)
protocol ItemEntity: AppEntity where ID == ItemIdentifier {
var id: ItemIdentifier { get set }
var item: OpenHABItem { get set }
Expand All @@ -24,7 +23,6 @@ protocol ItemEntity: AppEntity where ID == ItemIdentifier {
init(_ openHABItem: OpenHABItem, homeId: UUID, homeName: String?)
}

@available(iOS 17.0, macOS 14.0, *)
extension ItemEntity {
var homeId: UUID? {
id.homeId
Expand Down Expand Up @@ -58,13 +56,13 @@ extension ItemEntity {
var displayRepresentation: DisplayRepresentation {
if let homeName {
DisplayRepresentation(
title: nonLocalizedDisplayString(label, key: "__app_intents_item_label__"),
subtitle: nonLocalizedDisplayString("\(item.name) • \(homeName)", key: "__app_intents_item_subtitle__")
title: "\(label)",
subtitle: "\(item.name) • \(homeName)"
)
} else {
DisplayRepresentation(
title: nonLocalizedDisplayString(label, key: "__app_intents_item_label__"),
subtitle: nonLocalizedDisplayString(item.name, key: "__app_intents_item_name__")
title: "\(label)",
subtitle: "\(item.name)"
)
}
}
Expand All @@ -76,8 +74,4 @@ extension ItemEntity {
homeName: homeName
)
}

func nonLocalizedDisplayString(_ value: String, key: StaticString) -> LocalizedStringResource {
LocalizedStringResource(key, defaultValue: "\(value)")
}
}
2 changes: 0 additions & 2 deletions AppIntents/ItemEntityQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ import OpenHABCore

// MARK: - Shared Query Protocol

@available(iOS 17.0, macOS 14.0, *)
protocol ItemEntityQuery: EntityStringQuery {
associatedtype EntityType: ItemEntity

var allowedTypes: [OpenHABItem.ItemType] { get }
var selectedHome: Home? { get }
}

@available(iOS 17.0, macOS 14.0, *)
extension ItemEntityQuery {
@MainActor
func getHomeName(for homeId: UUID) -> String? {
Expand Down
78 changes: 78 additions & 0 deletions AppIntents/OpenHABAppShortcutsProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2010-2026 Contributors to the openHAB project
//
// See the NOTICE file(s) distributed with this work for additional
// information.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0
//
// SPDX-License-Identifier: EPL-2.0

import AppIntents
internal import SFSafeSymbols

/// App Shortcuts Provider for openHAB app
///
/// This provider registers app shortcuts with iOS, enabling:
/// - Siri phrase suggestions (e.g., "Toggle Kitchen Light in openHAB")
/// - Shortcuts in Spotlight search
/// - Add to Home Screen functionality
/// - Siri Suggestions on lock screen and search
///
/// ## Design Note
/// Due to iOS AppShortcuts limitation of one parameter per phrase,
/// shortcuts are designed for specific, common actions:
/// - Toggle switch items (most common switch operation)
/// - Get item state (universal query)
/// - Open/Close roller shutters (specific directional commands)
///
/// The action is embedded in the phrase itself since we can only
/// pass the item name as a parameter.
///
/// ## SF Symbol Names
/// Apple's AppShortcut requires literal strings for `systemImageName` -
/// constants and SFSafeSymbols cannot be used due to compile-time metadata extraction.
/// Symbol names use SF Symbols naming convention (e.g., "light.beacon.max").
/// Reference: https://developer.apple.com/sf-symbols/
///
/// ## Note
/// This file was present in PR #742 but was missing from PR #1028.
/// Adding it restores iOS app shortcuts functionality.
///
/// ## Usage
/// This struct is automatically discovered by iOS at build time.
/// No explicit registration is required - just having this file
/// in the app target is sufficient.
///
/// ## References
/// - Apple Documentation: https://developer.apple.com/documentation/appintents/app-shortcuts
/// - PR #742: Original implementation
/// - PR #1028: Enhanced intent implementations
struct OpenHABAppShortcutsProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
// MARK: - Switch Control - Toggle Action

// Note: Since AppShortcuts only allow one parameter per phrase,
// the action (toggle) is embedded in the phrase itself

AppShortcut(
intent: SetSwitchItemIntent(),
phrases: [
"Toggle \(\.$itemEntity) in \(.applicationName)",
"Toggle switch \(\.$itemEntity) in \(.applicationName)"
],
shortTitle: "Toggle Switch",
systemImageName: "light.beacon.max" // SFSymbol: .lightBeaconMax
)

// Roller shutter and dimmer shortcuts are omitted: SetDimmerRollerValueIntent
// requires a value: Int parameter not present in the phrase, so Siri would
// prompt "what value?" after the phrase — poor UX. Dedicated open/close
// intents (no value parameter) would be needed to add shutter shortcuts.
}

/// The color used for shortcut tiles in the Shortcuts app and Siri interface
/// Orange matches the openHAB brand color
static let shortcutTileColor: ShortcutTileColor = .orange
}
Loading