用途
EnergyKit 用于向应用提供电网电力预测,帮助用户判断何时使用电力更合适。它能够识别电网上相对更清洁或更便宜的时段,使应用可以据此转移或减少用电负载。典型用途包括智能家居应用、电动汽车充电调度等场景。
该框架面向 Swift 6.3 / iOS 26+。需要注意其处于 Beta 敏感阶段:EnergyKit 是 iOS 26 新增框架,在正式版(GM)之前可能发生变化,依赖具体 API 细节前应重新核对 Apple 当前文档。
主要能力
EnergyKit 提供两项核心能力:
- 电力指引(Electricity Guidance):带时间权重的预测,告知应用何时电力更清洁或更便宜,以便设备转移或减少用电。
- 负载事件(Load Events):来自设备(电动汽车充电桩、暖通空调)的遥测数据回传给系统,用于跟踪应用对指引的遵循程度。
关键类型包括:ElectricityGuidance(带权重时间区间的预测数据)、ElectricityGuidance.Service(获取指引数据的接口)、ElectricityGuidance.Query(指定 shift 或 reduce 动作的查询)、ElectricityGuidance.Value(带 0.0–1.0 评分的时间区间)、EnergyVenue(注册用于能源管理的物理位置,如住宅)、ElectricVehicleLoadEvent(电动汽车充电桩遥测负载事件)、ElectricHVACLoadEvent(暖通空调系统遥测负载事件)、ElectricityInsightService(查询能源/运行洞察的服务)、ElectricityInsightRecord(按清洁度/电价细分的历史能源数据)、ElectricityInsightQuery(历史洞察数据查询)。
建议动作(Suggested Actions):.shift 适用于可将用电转移到其他时间的设备(如电动汽车充电);.reduce 适用于可降低用电而不停止的设备(如暖通空调回退)。
使用方式
设置:EnergyKit 需要 com.apple.developer.energykit 权限,需将其添加到应用的 entitlements 文件中。导入方式为 import EnergyKit。平台可用性为 iOS 26+、iPadOS 26+。
查询电力指引:使用 ElectricityGuidance.Service 获取某个场所的预测流。示例中通过 ElectricityGuidance.Query(suggestedAction: .shift) 构造查询,调用 service.guidance(using: query, at: venueID) 获得异步流,遍历 guidance 可读取 guidanceToken、interval、energyVenueID,并通过 options 判断是否包含 .guidanceIncorporatesRatePlan(已纳入费率计划数据)或 .locationHasRatePlan(位置有费率计划)。
处理指引值:每个 ElectricityGuidance.Value 包含一个时间区间和 0.0 到 1.0 的评分,评分越低表示越适合用电。示例中通过 values.min(by: { $0.rating < $1.rating }) 找到最佳充电窗口,通过阈值过滤(如 rating <= 0.3)找出所有“良好”窗口。
在 SwiftUI 中展示:示例用 List 遍历 values,以时间区间为标识,展示起止时间与评分指示器;评分指示器按阈值着色(≤0.3 绿色 Good,≤0.6 黄色 Fair,其余红色 Avoid)。
能源场所(Energy Venues):EnergyVenue 表示注册用于能源管理的物理位置。可通过 EnergyVenue.venues() 列出所有场所,通过 EnergyVenue.venue(for: id) 按 ID 获取,或通过 EnergyVenue.venue(matchingHomeUniqueIdentifier:) 获取与 HomeKit 家庭匹配的场所。场所属性包括 id 与 name。
提交负载事件:将设备用电数据回传系统,有助于系统改进未来指引的准确性。电动汽车充电桩负载事件示例构造 ElectricVehicleLoadEvent.Session(含 id、state、guidanceState,其中 guidanceState 包含 wasFollowingGuidance 与 guidanceToken),以及 ElectricVehicleLoadEvent.ElectricalMeasurement(含 stateOfCharge、direction、power、energy),再通过 venue.submitEvents([event]) 提交。暖通空调负载事件示例构造 ElectricHVACLoadEvent.Session 与 ElectricHVACLoadEvent.ElectricalMeasurement(stage:),同样通过 submitEvents 提交。会话状态包括:.begin(设备开始用电)、.active(设备正在用电,周期性更新)、.end(设备停止用电)。
电力洞察(Electricity Insights):使用 ElectricityInsightService 查询设备的历史能源与运行数据。示例构造 ElectricityInsightQuery(options 含 .cleanliness、.tariff,range 为 DateInterval,granularity 为 .daily,flowDirection 为 .imported),调用 service.energyInsights(forDeviceID:using:atVenue:) 获得流,遍历记录可读取 totalEnergy、dataByGridCleanliness?.cleaner 等。运行数据使用 runtimeInsights(forDeviceID:using:atVenue:)。粒度选项包括 .hourly、.daily、.weekly、.monthly、.yearly。完整洞察示例见 references/energykit-patterns.md。
常见错误
- 忘记 EnergyKit 权限:没有权限时所有 EnergyKit 调用会静默失败或抛错。需将 com.apple.developer.energykit 添加到 entitlements。
- 忽略不支持的地区:EnergyKit 并非在所有地区可用,需处理
.unsupportedRegion与.guidanceUnavailable错误。示例中通过捕获 EnergyKitError 并分别处理 unsupportedRegion、guidanceUnavailable、venueUnavailable、permissionDenied、serviceUnavailable、rateLimitExceeded 等情形。 - 丢弃指引令牌(guidance token):guidanceToken 将负载事件与影响它们的指引关联起来,必须存储并传递到负载事件提交中。
- 提交负载事件时缺少会话生命周期:应始终按 .begin、.active 更新、.end 的顺序提交。
- 在没有场所的情况下查询指引:EnergyKit 需要场所 ID,应先列出场所并选择合适的场所,而非使用硬编码 UUID。
审查清单
- 项目中已添加 com.apple.developer.energykit 权限
- 已处理 EnergyKitError.unsupportedRegion 并向用户显示消息
- 已优雅处理 EnergyKitError.permissionDenied
- 已存储指引令牌并传递给负载事件提交
- 查询指引前已通过 EnergyVenue.venues() 发现场所
- 负载事件会话遵循 .begin -> .active -> .end 生命周期
- 正确解读 ElectricityGuidance.Value.rating(越低越好)
- SuggestedAction 与设备类型匹配(电动汽车用 .shift,暖通空调用 .reduce)
- 洞察查询对时间范围使用合适的粒度
- 已通过 EnergyKitError.rateLimitExceeded 处理限流
- 已用重试逻辑处理服务不可用
适用场景与限制
适用场景:构建智能家居应用、电动汽车充电调度等需要根据电网清洁度或电价优化家庭用电的应用。
限制:需要 com.apple.developer.energykit 权限;仅支持 iOS 26+ 与 iPadOS 26+;并非所有地区可用,需处理不支持地区与指引不可用等错误;处于 Beta 阶段,API 在正式版前可能变化;存在限流与服务不可用情况,需要相应处理。
参考资料
- 扩展模式(完整应用架构、SwiftUI 仪表盘):references/energykit-patterns.md
- EnergyKit framework
- ElectricityGuidance
- ElectricityGuidance.Service
- ElectricityGuidance.Query
- ElectricityGuidance.Value
- EnergyVenue
- ElectricVehicleLoadEvent
- ElectricHVACLoadEvent
- ElectricityInsightService
- ElectricityInsightRecord
- ElectricityInsightQuery
- EnergyKitError