灯具设备指南

灯具设备使用标准 Matter 特征来识别灯具、切换电源状态和调整亮度。

最基本的灯具设备类型是 OnOffLightDeviceType,它通过 OnOffTrait 和 IdentifyTrait 特性实现,并可选择支持 LevelControlTrait 特性和 LightEffectsTrait 特性。

其他灯光类型提供更多功能,并使用不同的 trait 实现:

Home API 设备类型 特征 Swift 示例应用 使用场景

色温灯

ColorTemperatureLightDeviceType

home.matter.0000.types.010c

一种照明设备,可开关、可调节光线强度和色温。

必需的特征
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait
     matter ColorControlTrait

可选特征
     google LightEffectsTrait
     google ExtendedColorControlTrait
浅色

可调光灯

DimmableLightDeviceType

home.matter.0000.types.0101

一种照明设备,能够开关、调节光线强度,并通过绑定的在家/外出传感器进行切换。

必需的特征
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait

可选特征
     google LightEffectsTrait
浅色

扩展彩色灯

ExtendedColorLightDeviceType

home.matter.0000.types.010d

一种照明设备,能够开启或关闭、调节光线强度、调节色温,并可通过绑定的在家/外出传感器进行切换。

必需的特征
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait
     matter ColorControlTrait

可选特征
     google LightEffectsTrait
     google ExtendedColorControlTrait
浅色

开/关灯

OnOffLightDeviceType

home.matter.0000.types.0100

可以开启或关闭的照明设备。

必需的特征
     matter IdentifyTrait
     matter OnOffTrait

可选特征
     matter LevelControlTrait
     google LightEffectsTrait
浅色

在使用任何功能或尝试更新属性之前,请务必检查设备是否支持相应属性和命令。如需了解详情,请参阅在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)
  }

获取设备的基本信息

   在 iOS 版示例应用中实现   

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)
}