灯具设备使用标准 Matter 特征来识别灯具、切换电源状态和调整亮度。
最基本的灯具设备类型是 OnOffLightDeviceType,它通过 OnOffTrait 和 IdentifyTrait 特性实现,并可选择支持 LevelControlTrait 特性和 LightEffectsTrait 特性。
其他灯光类型提供更多功能,并使用不同的 trait 实现:
| Home API 设备类型 | 特征 | Swift 示例应用 | 使用场景 |
|---|---|---|---|
|
色温灯
一种照明设备,可开关、可调节光线强度和色温。 |
必需的特征 matter IdentifyTrait matter OnOffTrait matter LevelControlTrait matter ColorControlTrait |
浅色 | |
|
可调光灯
一种照明设备,能够开关、调节光线强度,并通过绑定的在家/外出传感器进行切换。 |
必需的特征 matter IdentifyTrait matter OnOffTrait matter LevelControlTrait |
浅色 | |
|
扩展彩色灯
一种照明设备,能够开启或关闭、调节光线强度、调节色温,并可通过绑定的在家/外出传感器进行切换。 |
必需的特征 matter IdentifyTrait matter OnOffTrait matter LevelControlTrait matter ColorControlTrait |
浅色 | |
|
开/关灯
可以开启或关闭的照明设备。 |
必需的特征 matter IdentifyTrait matter OnOffTrait |
浅色 |
在使用任何功能或尝试更新属性之前,请务必检查设备是否支持相应属性和命令。如需了解详情,请参阅在iOS上控制设备。
前提条件
在使用照明设备和照明曲线之前,请确保您的应用初始化 Home SDK 并包含所需的导入内容:
import Foundation import GoogleHomeSDK import GoogleHomeTypes import Network
查找照明设备
如需查找结构中的照明设备,请按设备类型(例如 OnOffLightDeviceType 和 DimmableLightDeviceType)过滤设备列表。
let allDevices = try await home.devices().list() // Get all On/Off Light devices in the structure let onOffLights = allDevices.filter { $0.types.contains(OnOffLightDeviceType.self) } // Get all Dimmable Light devices in the structure let dimmableLights = allDevices.filter { $0.types.contains(DimmableLightDeviceType.self) } // Retrieve a specific device type instance to access its traits let onOffLightDeviceType = await onOffLights.first?.types.get(OnOffLightDeviceType.self) let dimmableLightDeviceType = await dimmableLights.first?.types.get(DimmableLightDeviceType.self)
您还可以在单个过滤条件中检索多种照明设备类型的所有照明设备:
// Get a list of devices with similar device types (lights) let lightDevices = try await self.home.devices().list().compactMap { $0.types.contains(DimmableLightDeviceType.self) || $0.types.contains(OnOffLightDeviceType.self) || $0.types.contains(ColorTemperatureLightDeviceType.self) || $0.types.contains(ExtendedColorLightDeviceType.self) }
获取设备的基本信息
BasicInformation 特征包含供应商名称、供应商 ID、产品 ID、商品名称(包含型号信息)和设备软件版本等信息:
let vendorName = basicInfoTrait.attributes.vendorName! let vendorID = basicInfoTrait.attributes.vendorID! let productID = basicInfoTrait.attributes.productID! let productName = basicInfoTrait.attributes.productName! let softwareVersion = basicInfoTrait.attributes.softwareVersion!
识别照明设备
当一个房间内有多个灯具时,您可以通过触发视觉识别状态(例如让灯具闪烁几秒钟),帮助用户找到特定的实体灯具。所有四种灯具设备类型都需要 Matter.IdentifyTrait 特征。
使用 identifyTime 持续时间(以秒为单位)调用 identify 命令,以启动识别状态。传递 0 会立即停止识别状态。您还可以调用 triggerEffect 来运行特定的视觉效果,例如 Blink 或 Breathe。
func identifyLight(lightDeviceType: DimmableLightDeviceType) async throws {
guard let identifyTrait = lightDeviceType.matterTraits.identifyTrait else {
return
}
// Blink the light for 10 seconds so the user can locate it
if identifyTrait.supportsIdentifyCommand {
try await identifyTrait.identify(identifyTime: 10)
}
// Or trigger a specific visual identification effect
if identifyTrait.supportsTriggerEffectCommand {
try await identifyTrait.triggerEffect(
effectIdentifier: .blink,
effectVariant: .default
)
}
}
检查照明设备的连接性
设备的连接性实际上是在设备类型级别进行检查的,因为某些设备支持多种设备类型。返回的状态是该设备上所有特征的连接状态的组合。
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
如果设备类型不一致,且未连接到互联网,则可能会观察到 partiallyOnline 状态。由于本地路由,Matter 标准特性可能仍处于在线状态,但基于云的特性将处于离线状态。
获取设备的 IP 地址
如需查找设备的 IP 地址,请使用 GeneralDiagnosticsTrait 的 networkInterfaces 属性。这些地址会作为 Data 对象返回,您可以使用 Network 框架将其格式化为标准 IPv4 或 IPv6 字符串:
func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
let interfaces = trait.attributes.networkInterfaces ?? []
var ipAddresses: [String] = []
for interface in interfaces {
for data in interface.iPv4Addresses {
if let ipv4 = IPv4Address(data) {
ipAddresses.append(String(describing: ipv4))
}
}
for data in interface.iPv6Addresses {
if let ipv6 = IPv6Address(data) {
ipAddresses.append(String(describing: ipv6))
}
}
}
return ipAddresses
}
控制照明设备
OnOffLight 和 DimmableLight 设备类型使用标准 Matter 特征来识别灯具、切换电源状态和调整亮度级别。
开灯或关灯
使用 OnOffTrait 特性可读取 OnOffLight 或 DimmableLight 的当前电源状态,以及开启或关闭灯。
在读取 onOff 属性之前,请验证设备是否支持该属性。某些设备作为仅命令端点运行,不报告状态。
// Check if the OnOff trait supports the onOff attribute. if onOffTrait.attributes.$onOff.isSupported { print("onOffTrait supports onOff state") } else { print("onOffTrait is for a command only device!") }
当 onOff 为 true 时,灯会亮起。当 onOff 为 false 时,指示灯熄灭。
如需更改灯具的电源状态,请验证该 trait 是否支持预期命令,然后调用 on()、off() 或 toggle()。
// Check if the OnOff trait supports the toggle command. if onOffTraitTest.supportsToggleCommand { print("onOffTrait supports toggle command") } else { print("onOffTrait does not support stateful toggle command") }
// Calling a command on a trait. do { try await onOffTraitTest.toggle() } catch let _ as HomeError { // Code for handling the exception }
您也可以直接调用 on() 和 off() 来设置明确的状态:
do { try await onOffTraitTest.off() try await onOffTraitTest.on() } catch let _ as HomeError { // Code for handling the exception }
如需通过渐变视觉过渡效果关闭灯,请调用 offWithEffect() 并指定 EffectIdentifierEnum 值:
// Turn off the light using the DyingLight effect. do { try await onOffTraitTest.offWithEffect( effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight, effectVariant: 0 ) } catch let _ as HomeError { // Code for handling the exception }
调整亮度级别
DimmableLight 需要 LevelControlTrait 特征,而 OnOffLight 可以选择支持该特征。使用此 trait 可读取和控制灯的亮度级别。
currentLevel 属性会报告当前亮度级别,范围为 0 到 254。您还可以检查 minLevel 和 maxLevel,以确定硬件支持的有效亮度范围。
如需将亮度设置为特定值,请调用 moveToLevel()。请注意,除非您将 optionsOverride 配置为 executeIfOff,否则 moveToLevel() 仅在灯已亮起时更改当前亮度。如需在设置非零亮度级别时自动开灯(或在将亮度级别设置为最低时关灯),请使用 moveToLevelWithOnOff()。
// Change the brightness of the light to 50% do { try await levelControlTraitTest.moveToLevel( level: UInt8(127), transitionTime: 0, optionsMask: Matter.LevelControlTrait.OptionsBitmap(), optionsOverride: Matter.LevelControlTrait.OptionsBitmap() ) } catch let _ as HomeError { // Code for handling the exception }
以下示例会读取当前亮度,并使用 moveToLevelWithOnOff() 在 1 秒(10 秒)的过渡时间内将可调光灯具设置为 75% 亮度 (190):
func setLightBrightness(lightDeviceType: DimmableLightDeviceType) async throws { guard let levelControl = lightDeviceType.matterTraits.levelControlTrait else { return } // Read the current brightness level (0 to 254) let currentLevel: UInt8? = levelControl.attributes.currentLevel print("Current brightness level: \(String(describing: currentLevel))") // Move to ~75% brightness (190 out of 254) and turn on the light if it is off if levelControl.supportsMoveToLevelWithOnOffCommand { try await levelControl.moveToLevelWithOnOff( level: UInt8(190), transitionTime: 10, optionsMask: Matter.LevelControlTrait.OptionsBitmap(), optionsOverride: Matter.LevelControlTrait.OptionsBitmap() ) } }
您还可以通过使用 .up 或 .down 以及 stepSize 调用 stepWithOnOff(),相对于当前级别增加或减少亮度。
控件颜色
ColorControlTrait 特征在 ColorTemperatureLightDeviceType 和 ExtendedColorLightDeviceType 中均可用。
此 trait 可让您以微倒数度或迈尔德为单位调整色温。
guard let colorControlTrait = colorTempLightDeviceType.matterTraits.colorControlTrait else { return } // Read the current color temperature and hardware limits in mireds // (Mireds = 1,000,000 / Kelvin; e.g., 370 mireds ≈ 2700K warm white, 250 mireds = 4000K cool white) let currentMireds = colorControlTrait.attributes.colorTemperatureMireds let minMireds = colorControlTrait.attributes.colorTempPhysicalMinMireds ?? 153 let maxMireds = colorControlTrait.attributes.colorTempPhysicalMaxMireds ?? 500 // Clamp target (370 mireds ≈ 2700K) to the device's physical bounds let targetMireds = min(max(UInt16(370), minMireds), maxMireds) if colorControlTrait.supportsMoveToColorTemperatureCommand { try await colorControlTrait.moveToColorTemperature( colorTemperatureMireds: targetMireds, transitionTime: 20, // 2.0 seconds (in 0.1s units) optionsMask: Matter.ColorControlTrait.OptionsBitmap(), optionsOverride: Matter.ColorControlTrait.OptionsBitmap() ) }
您还可以使用 CIE 1931 色度坐标以及 16 位色调和饱和度值来设置颜色。
guard let colorControlTrait = extendedColorLightDeviceType.matterTraits.colorControlTrait else { return } // 1. Move to CIE 1931 xy chromaticity coordinates (scaled 0..65279) // Example: x = 0.3127 (20493), y = 0.3290 (21561) for D65 white point if colorControlTrait.supportsMoveToColorCommand { try await colorControlTrait.moveToColor( colorX: 20493, colorY: 21561, transitionTime: 10, // 1.0 second (in 0.1s units) optionsMask: Matter.ColorControlTrait.OptionsBitmap(), optionsOverride: Matter.ColorControlTrait.OptionsBitmap() ) } let currentX = colorControlTrait.attributes.currentX let currentY = colorControlTrait.attributes.currentY // 2. Move to 16-bit Enhanced Hue (0..65534) and 8-bit Saturation (0..254) if colorControlTrait.supportsEnhancedMoveToHueAndSaturationCommand { try await colorControlTrait.enhancedMoveToHueAndSaturation( enhancedHue: 43690, // ~240° (Blue) on the 0..65534 scale saturation: 254, // Full saturation transitionTime: 15, // 1.5 seconds (in 0.1s units) optionsMask: Matter.ColorControlTrait.OptionsBitmap(), optionsOverride: Matter.ColorControlTrait.OptionsBitmap() ) } // 3. Start a hardware color loop across the device's hue range if colorControlTrait.supportsColorLoopSetCommand { try await colorControlTrait.colorLoopSet( updateFlags: [ .updateAction, .updateDirection, .updateTime, .updateStartHue ], action: .activateFromColorLoopStartEnhancedHue, direction: .increment, time: 30, // 30 seconds per full cycle startHue: 0, optionsMask: Matter.ColorControlTrait.OptionsBitmap(), optionsOverride: Matter.ColorControlTrait.OptionsBitmap() ) }
Google.ExtendedColorControlTrait 是 ExtendedColorLightDevice 的可选 Google 特性,它通过接受颜色名称、RGB 值或将颜色和亮度组合在单个单元中的统一浮点 HSV 值来简化颜色控制。
guard let extendedColorControlTrait = extendedColorLightDeviceType.googleTraits.extendedColorControlTrait else { return } // 1. Set color by name if extendedColorControlTrait.supportsMoveToColorNameCommand { try await extendedColorControlTrait.moveToColorName(colorName: "Lavender") } let currentColorName = extendedColorControlTrait.attributes.currentName // 2. Set color using 8-bit RGB values (0..255 per channel) // Automatically coordinates brightness (LevelControl) and color (ColorControl) if extendedColorControlTrait.supportsMoveToColorRGBCommand { try await extendedColorControlTrait.moveToColorRGB( red: 255, green: 128, blue: 0 ) } let currentRed = extendedColorControlTrait.attributes.currentRed let currentGreen = extendedColorControlTrait.attributes.currentGreen let currentBlue = extendedColorControlTrait.attributes.currentBlue // 3. Set color and brightness together using floating-point HSV // hue: 0.0...360.0, saturation: 0.0...1.0, value (brightness): 0.0...1.0 if extendedColorControlTrait.supportsMoveToColorHSVCommand { try await extendedColorControlTrait.moveToColorHSV( hue: 210.0, saturation: 0.85, value: 0.75 ) } let currentHue = extendedColorControlTrait.attributes.currentHue let currentSaturation = extendedColorControlTrait.attributes.currentSaturation let currentValue = extendedColorControlTrait.attributes.currentValue
管理光照曲线
光照曲线定义了一个自动化时间表,可在一天中平滑地转换目标灯具的亮度和可选色温。例如,照明曲线可以在早晨逐渐调亮灯光,在晚上将灯光调暗至更温暖的色调。仅支持亮度的灯具设备类型(例如可调光灯)会遵循亮度曲线,并忽略色温。
Google.LightingCurveTrait 特性是结构级 Google Home platform (GHP) 特性。您可以通过 Structure 实例(而非单个照明设备)访问它。
此 trait 上的每个时间表都由一个 LightingCurveSetting 表示,它将唯一的 settingId 与 LightingCurveConfig 配对。下表介绍了 LightingCurveConfig 的配置字段:
| 字段 | 说明 |
|---|---|
curvePointsArray |
至少两个 CurvePoint 项的序列,且时间各不相同。每个点都指定一个 time(CurveTimeOfDay,hours 范围为 0 到 23,minutes 范围为 0 到 59)、一个 brightnessPercent(0 到 100)和一个可选的 colorTemperature(以开尔文为单位)。如果为任何点指定了 colorTemperature,则所有点的 colorTemperature 都必须为正值。 |
roomId |
目标房间的 ID(例如 room@{uuid})。将光照曲线应用于该房间内兼容的可调光和色温灯具。请指定 roomId 或 devices。 |
devices |
一个 TargetDevices 对象,其中包含 TargetDevice 条目列表,每个条目都有一个设备 id 和设备 type ID(例如 DimmableLight 的 home.matter.0000.types.0101 或 ColorTemperatureLight 的 home.matter.0000.types.010c)。请指定 devices 或 roomId。 |
daysOfWeekArray |
照明曲线在每周内的哪些天运行 (Locale.Weekday)。如果列表为空,则照明曲线每天运行。 |
adaptive |
可选布尔值,用于指明光照曲线是否为自适应,即目标灯具在预约时限范围内开启时是否会恢复到有效曲线级别。如果设为 false,手动更改灯光设置后,灯光在当天剩余时间内将不再遵循光照曲线。如果设为 true,在预约时限内关闭并重新打开灯具后,灯具会重新应用照明曲线,使其符合曲线的当前亮度和色温,并从该点开始遵循曲线。 |
enabled |
可选布尔值,用于指示光照曲线设置是否处于启用状态。创建新设置时,默认值为 true。如果更新命令中省略了 enabled,则 enabled 的状态不会更改。 |
读取光效曲线设置
如需检查为结构配置的光照曲线,请从 Structure 中检索 Google.LightingCurveTrait 特性,并读取其 lightingCurveSettingsArray 属性。
func readLightingCurves(structure: Structure) async {
guard let lightingCurve = await structure.traits.get(
Google.LightingCurveTrait.self
) else {
return
}
for setting in lightingCurve.attributes.lightingCurveSettingsArray {
let settingId = setting.settingId
let config = setting.config
print(
"Setting ID: \(String(describing: settingId)), " +
"enabled: \(String(describing: config?.enabled))"
)
for point in config?.curvePointsArray ?? [] {
print(
" Time: \(point.time?.hours ?? 0):\(point.time?.minutes ?? 0), " +
"Brightness: \(point.brightnessPercent ?? 0)%, " +
"ColorTemp: \(point.colorTemperature ?? 0)K"
)
}
}
}
创建光效曲线设置
如需在结构体上创建新的光照曲线时间表,请构建一个 LightingCurveConfig,其中至少包含两个 CurvePoint 条目、目标灯(由 roomId 或 devices 指定)以及一周中的有效日期。然后,将配置传递给 createLightingCurveSetting()。该命令会返回分配给新光照曲线设置的唯一 settingId。
以下示例为某个房间创建了一个工作日灯光曲线,该曲线在上午 7:00 将亮度从 30% 提升到上午 9:00 的 80%,并在晚上 9:00 将亮度调暗到 20%:
func createRoomLightingCurve(
structure: Structure,
targetRoomId: String
) async throws -> String? {
guard let lightingCurve = await structure.traits.get(
Google.LightingCurveTrait.self
) else {
return nil
}
let curvePoints = [
Google.LightingCurveTrait.CurvePoint(
time: Google.LightingCurveTrait.CurveTimeOfDay(hours: 7, minutes: 0),
brightnessPercent: 30,
colorTemperature: 2700
),
Google.LightingCurveTrait.CurvePoint(
time: Google.LightingCurveTrait.CurveTimeOfDay(hours: 9, minutes: 0),
brightnessPercent: 80,
colorTemperature: 4000
),
Google.LightingCurveTrait.CurvePoint(
time: Google.LightingCurveTrait.CurveTimeOfDay(hours: 21, minutes: 0),
brightnessPercent: 20,
colorTemperature: 2200
),
]
let config = Google.LightingCurveTrait.LightingCurveConfig(
curvePointsArray: curvePoints,
roomId: targetRoomId,
daysOfWeekArray: [
.monday,
.tuesday,
.wednesday,
.thursday,
.friday,
],
adaptive: true,
enabled: true
)
let response = try await lightingCurve.createLightingCurveSetting(
config: config
)
return response.settingId
}
如需定位到特定照明设备(而非整个房间),请使用 Google.LightingCurveTrait.TargetDevices 提供 devices 参数:
let targetDevices = Google.LightingCurveTrait.TargetDevices(
devicesArray: [
Google.LightingCurveTrait.TargetDevice(
id: dimmableLight.id,
type: DimmableLightDeviceType.identifier
)
]
)
let deviceCurveConfig = Google.LightingCurveTrait.LightingCurveConfig(
curvePointsArray: curvePoints,
devices: targetDevices,
daysOfWeekArray: [.saturday, .sunday],
adaptive: true,
enabled: true
)
let response = try await lightingCurve.createLightingCurveSetting(
config: deviceCurveConfig
)
let settingId = response.settingId
更新光照曲线设置
如需修改现有光照曲线(例如更改其曲线点、更新一周中的有效日期,或启用和停用时间表),请使用目标 settingId 和更新后的 LightingCurveConfig 调用 updateLightingCurveSetting()。
func updateLightingCurve(
structure: Structure,
settingId: String,
updatedConfig: Google.LightingCurveTrait.LightingCurveConfig
) async throws {
guard let lightingCurve = await structure.traits.get(
Google.LightingCurveTrait.self
) else {
return
}
_ = try await lightingCurve.updateLightingCurveSetting(
settingId: settingId,
config: updatedConfig
)
}
删除光效曲线设置
如需从结构中移除光照曲线设置,请使用要删除的设置的 settingId 调用 deleteLightingCurveSetting()。
func deleteLightingCurve(
structure: Structure,
settingId: String
) async throws {
guard let lightingCurve = await structure.traits.get(
Google.LightingCurveTrait.self
) else {
return
}
_ = try await lightingCurve.deleteLightingCurveSetting(settingId: settingId)
}