Copilot 6916e5437b
Add fan entity type to Control Center controls (#4109)
## Summary
Adds fan domain support to iOS 18 Control Center controls. Users can now
toggle fan entities directly from Control Center alongside existing
light, switch, and cover controls.

## Screenshots

N/A - Control Center widget requires device testing with configured fan
entities

## Link to pull request in Documentation repository

Documentation: home-assistant/companion.home-assistant#

## Any other notes

**Implementation:**
- Added `fan` domain to `Domain` enum with on/off states and CarPlay
support
- Created `ControlFan` widget with 4 files following existing control
patterns:
  - Main widget configuration with blue tint
  - Intent handler for toggle/turn_on/turn_off services
- Entity query with async pattern (matching Switch/Cover for
future-proofing)
- Value provider for state management with SF Symbol icons
(`fan`/`fan.fill`) and optional displayText parameter
- Integrated fan domain into system components:
  - `HAAPI.swift` - Added to toggle domain case
  - `HAEntity+CarPlay.swift` - Added fan icon mapping
  - `MagicItem.swift` - Added to toggle domain case
- Registered as `controlFan` in `WidgetsKind` and `WidgetsBundle18`
- Added localization strings following established patterns ("Choose
fan" for consistency)
- Added optional `displayText` parameter to `ControlFanConfiguration`
for custom display names (matching PR #4104 pattern)

**Pattern consistency:**
Mirrors Switch/Cover implementations with async entity queries. Uses
standard on/off toggle model with state-based icons. Includes
displayText override feature for user customization.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Add "fan" entity type to control center
controls</issue_title>
> <issue_description>
> ### Discussed in
https://github.com/home-assistant/iOS/discussions/3679
> 
> <div type='discussions-op-text'>
> 
> <sup>Originally posted by **haydonryan** June 29, 2025</sup>
> Currently on IOS we have most of the major types except for fans.
Could we add that too please?
> 
>
![image](https://github.com/user-attachments/assets/6bef25db-f706-45f8-92cb-5940b5f0f7c4)</div></issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes home-assistant/iOS#3681

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 16:15:02 +00:00

34 lines
1.1 KiB
Swift

import AppIntents
import Foundation
import Shared
import SwiftUI
import WidgetKit
@available(iOS 18, *)
struct ControlFan: ControlWidget {
var body: some ControlWidgetConfiguration {
AppIntentControlConfiguration(
kind: WidgetsKind.controlFan.rawValue,
provider: ControlFanValueProvider()
) { template in
ControlWidgetToggle(isOn: template.value, action: {
let intent = FanIntent()
intent.fan = .init(
id: template.id,
entityId: template.entityId,
serverId: template.serverId,
displayString: template.name,
iconName: template.icon.id
)
intent.value = !template.value
return intent
}()) {
Label(template.name, systemImage: template.icon.id)
}
.tint(.blue)
}
.displayName(.init(stringLiteral: L10n.Widgets.Controls.Fan.title))
.description(.init(stringLiteral: L10n.Widgets.Controls.Fan.description))
}
}