灯具设备指南

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

最基本的灯具设备类型是 OnOffLight,它通过 OnOff 和 Identify 特性实现,并可选择支持 LevelControl 特性和 LightEffects 特性。

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

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

色温灯

ColorTemperatureLightDevice

home.matter.0000.types.010c

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

必需的特征
     matter Identify
     matter OnOff
     matter LevelControl
     matter ColorControl

可选特征
     google LightEffects
     google ExtendedColorControl

开关、亮度
浅色

可调光灯

DimmableLightDevice

home.matter.0000.types.0101

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

必需的特征
     matter Identify
     matter OnOff
     matter LevelControl

可选特征
     google LightEffects

开关、亮度
浅色

扩展彩色灯

ExtendedColorLightDevice

home.matter.0000.types.010d

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

必需的特征
     matter Identify
     matter OnOff
     matter LevelControl
     matter ColorControl

可选特征
     google LightEffects
     google ExtendedColorControl

开关、亮度
浅色

开/关灯

OnOffLightDevice

home.matter.0000.types.0100

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

必需的特征
     matter Identify
     matter OnOff

可选特征
     matter LevelControl
     google LightEffects

开关、亮度
浅色

在使用任何功能或尝试更新属性之前,请务必检查设备是否支持相应属性和命令。如需了解详情,请参阅在Android上控制设备。

前提条件

在使用照明设备和照明曲线之前,请确保您的应用初始化 Home SDK 并包含所需的导入内容:

import com.google.home.HomeDevice
import com.google.home.Structure
import com.google.home.google.DayOfWeek
import com.google.home.google.ExtendedColorControl
import com.google.home.google.ExtendedColorControlTrait
import com.google.home.google.LightingCurve
import com.google.home.google.LightingCurveTrait
import com.google.home.matter.standard.ColorControl
import com.google.home.matter.standard.ColorControlTrait
import com.google.home.matter.standard.ColorTemperatureLightDevice
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.ExtendedColorLightDevice
import com.google.home.matter.standard.GeneralDiagnostics
import com.google.home.matter.standard.Identify
import com.google.home.matter.standard.IdentifyTrait
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffLightDevice
import com.google.home.matter.standard.OnOffTrait
import com.google.home.matter.standard.RootNodeDevice
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull

查找照明设备

如需查找结构中的照明设备,请按设备类型(例如 OnOffLightDevice 和 DimmableLightDevice)过滤设备列表。

// Get all On/Off Light devices in the structure
val onOffLights: List<HomeDevice> =
  home.devices().list().filter { it.has(OnOffLightDevice) }

// Get all Dimmable Light devices in the structure
val dimmableLights: List<HomeDevice> =
  home.devices().list().filter { it.has(DimmableLightDevice) }

// Retrieve a specific device type instance to access its traits
val onOffLightDevice: OnOffLightDevice? =
  onOffLights.firstOrNull()?.type(OnOffLightDevice)?.firstOrNull()

val dimmableLightDevice: DimmableLightDevice? =
  dimmableLights.firstOrNull()?.type(DimmableLightDevice)?.firstOrNull()

您还可以在单个过滤条件中检索多种照明设备类型的所有照明设备:

// Get a list of devices with similar device types (lights)
val lightDevices =
  home.devices().map { devices ->
    devices.filter {
      it.has(DimmableLightDevice) ||
        it.has(OnOffLightDevice) ||
        it.has(ColorTemperatureLightDevice) ||
        it.has(ExtendedColorLightDevice)
    }
  }

获取设备的基本信息

   在 Android 示例应用中实现   

BasicInformation 特征包含供应商名称、供应商 ID、产品 ID、商品名称(包含型号信息)和设备软件版本等信息:

// Get device basic information. All general information traits are on the RootNodeDevice type.
    device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation ->
        println("vendorName ${basicInformation.vendorName}")
        println("vendorId ${basicInformation.vendorId}")
        println("productId ${basicInformation.productId}")
        println("productName ${basicInformation.productName}")
        println("softwareVersion ${basicInformation.softwareVersion}")
    }

识别照明设备

当一个房间内有多个灯具时,您可以通过触发视觉识别状态(例如让灯具闪烁几秒钟),帮助用户找到特定的实体灯具。所有四种灯具设备类型都需要 Identify 特征。

使用 identifyTime 持续时间(以秒为单位)调用 identify 命令,以启动识别状态。传递 0 会立即停止识别状态。您还可以调用 triggerEffect 来运行特定的视觉效果,例如 Blink 或 Breathe。

suspend fun identifyLight(lightDevice: DimmableLightDevice) {
  val identifyTrait = lightDevice.standardTraits.identify ?: return

  // Blink the light for 10 seconds so the user can locate it
  if (identifyTrait.supports(Identify.Command.Identify)) {
    identifyTrait.identify(identifyTime = 10u)
  }

  // Or trigger a specific visual identification effect
  if (identifyTrait.supports(Identify.Command.TriggerEffect)) {
    identifyTrait.triggerEffect(
      effectIdentifier = IdentifyTrait.EffectIdentifierEnum.Blink,
      effectVariant = IdentifyTrait.EffectVariantEnum.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 特征来识别灯具、切换电源状态和调整亮度级别。

开灯或关灯

使用 OnOff 特性可读取 OnOffLight 或 DimmableLight 的当前电源状态,以及开启或关闭灯。

在读取 onOff 属性之前,请验证设备是否支持该属性。某些设备作为仅命令端点运行,不报告状态。

// Check if the OnOff trait supports the onOff attribute.
if (onOffTrait.supports(OnOff.Attribute.onOff)) {
  println("onOffTrait supports onOff state")
} else {
  println("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 (onOffTrait.supports(OnOff.Command.Toggle)) {
  println("onOffTrait supports toggle command")
} else {
  println("onOffTrait does not support stateful toggle command")
}
// Calling a command on a trait.
try {
  onOffTrait.toggle()
} catch (e: HomeException) {
  // Code for handling the exception
}

您也可以直接调用 on() 和 off() 来设置明确的状态:

onOffTrait.off()
onOffTrait.on()

如需通过渐变视觉过渡效果关闭灯,请调用 offWithEffect() 并指定 EffectIdentifierEnum 值:

// Turn off the light using the DyingLight effect.
onOffTrait.offWithEffect(
  effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight,
  effectVariant = 0u,
)

调整亮度级别

DimmableLight 需要 LevelControl 特征,OnOffLight 可以选择支持该特征。使用此 trait 可读取和控制灯光的亮度级别。

currentLevel 属性会报告当前亮度级别,范围为 0 到 254。您还可以检查 minLevel 和 maxLevel,以确定硬件支持的有效亮度范围。

如需将亮度设置为特定值,请调用 moveToLevel()。请注意,除非您将 optionsOverride 配置为 executeIfOff,否则 moveToLevel() 仅在灯已亮起时更改当前亮度。如需在设置非零亮度级别时自动开灯(或在将亮度级别设置为最低时关灯),请使用 moveToLevelWithOnOff()。

// Change the brightness of the light to 50%
levelControlTrait.moveToLevel(
  level = 127u.toUByte(),
  transitionTime = null,
  optionsMask = LevelControlTrait.OptionsBitmap(),
  optionsOverride = LevelControlTrait.OptionsBitmap(),
)

以下示例会读取当前亮度,并使用 moveToLevelWithOnOff() 在 1 秒(10u 秒)的过渡时间内将可调光灯具设置为 75% 亮度 (190u):

suspend fun setLightBrightness(lightDevice: DimmableLightDevice) {
  val levelControl = lightDevice.standardTraits.levelControl ?: return

  // Read the current brightness level (0 to 254)
  val currentLevel: UByte? = levelControl.currentLevel
  println("Current brightness level: $currentLevel")

  // Move to ~75% brightness (190 out of 254) and turn on the light if it is off
  if (levelControl.supports(LevelControl.Command.MoveToLevelWithOnOff)) {
    levelControl.moveToLevelWithOnOff(
      level = 190u,
      transitionTime = 10u,
      optionsMask = LevelControlTrait.OptionsBitmap(),
      optionsOverride = LevelControlTrait.OptionsBitmap()
    )
  }
}

您还可以通过调用 stepWithOnOff()(使用 StepModeEnum.Up 或 StepModeEnum.Down 以及 stepSize)来相对于当前级别增加或减少亮度。

控件颜色

ColorControl 特征在 ColorTemperatureLightDevice 和 ExtendedColorLightDevice 中均可用。

此 trait 可让您以微倒数度或迈尔德为单位调整色温。

val colorControlTrait =
  colorTempLightDevice.standardTraits.colorControl ?: 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)
val currentMireds = colorControlTrait.colorTemperatureMireds
val minMireds = colorControlTrait.colorTempPhysicalMinMireds ?: 153u // ~6500K (coolest)
val maxMireds = colorControlTrait.colorTempPhysicalMaxMireds ?: 500u // 2000K (warmest)
// Clamp target (370 mireds ≈ 2700K) to the device's physical bounds
val targetMireds = 370u.toUShort().coerceIn(minMireds, maxMireds)
if (
  colorControlTrait.supports(
    ColorControl.Command.MoveToColorTemperature
  )
) {
  colorControlTrait.moveToColorTemperature(
    colorTemperatureMireds = targetMireds,
    transitionTime = 20u, // 2.0 seconds (in 0.1s units)
    optionsMask = ColorControlTrait.OptionsBitmap(),
    optionsOverride = ColorControlTrait.OptionsBitmap()
  )
}

您还可以使用 CIE 1931 色度坐标以及 16 位色调和饱和度值来设置颜色。

val colorControlTrait =
  extendedColorLightDevice.standardTraits.colorControl ?: 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.supports(ColorControl.Command.MoveToColor)) {
  colorControlTrait.moveToColor(
    colorX = 20493u,
    colorY = 21561u,
    transitionTime = 10u, // 1.0 second (in 0.1s units)
    optionsMask = ColorControlTrait.OptionsBitmap(),
    optionsOverride = ColorControlTrait.OptionsBitmap()
  )
}
val currentX = colorControlTrait.currentX
val currentY = colorControlTrait.currentY
// 2. Move to 16-bit Enhanced Hue (0..65534) and 8-bit Saturation (0..254)
if (
  colorControlTrait.supports(
    ColorControl.Command.EnhancedMoveToHueAndSaturation
  )
) {
  colorControlTrait.enhancedMoveToHueAndSaturation(
    enhancedHue = 43690u, // ~240° (Blue) on the 0..65534 scale
    saturation = 254u,    // Full saturation
    transitionTime = 15u, // 1.5 seconds (in 0.1s units)
    optionsMask = ColorControlTrait.OptionsBitmap(),
    optionsOverride = ColorControlTrait.OptionsBitmap()
  )
}
// 3. Start a hardware color loop across the device's hue range
if (colorControlTrait.supports(ColorControl.Command.ColorLoopSet)) {
  colorControlTrait.colorLoopSet(
    updateFlags =
      ColorControlTrait.UpdateFlagsBitmap(
        updateAction = true,
        updateDirection = true,
        updateTime = true,
        updateStartHue = true
      ),
    action =
      ColorControlTrait.ColorLoopActionEnum
        .ActivateFromColorLoopStartEnhancedHue,
    direction = ColorControlTrait.ColorLoopDirectionEnum.Increment,
    time = 30u, // 30 seconds per full cycle
    startHue = 0u,
    optionsMask = ColorControlTrait.OptionsBitmap(),
    optionsOverride = ColorControlTrait.OptionsBitmap()
  )
}

ExtendedColorControl 是 ExtendedColorLightDevice 的可选 Google 特性,它通过接受颜色名称、RGB 值或将颜色和亮度组合在单个单元中的统一浮点 HSV 值来简化颜色控制。

val extendedColorControlTrait =
  extendedColorLightDevice.googleTraits.extendedColorControl ?: return
// 1. Set color by name
if (
  extendedColorControlTrait.supports(
    ExtendedColorControl.Command.MoveToColorName
  )
) {
  extendedColorControlTrait.moveToColorName(colorName = "Lavender")
}
val currentColorName = extendedColorControlTrait.currentName
// 2. Set color using 8-bit RGB values (0..255 per channel)
// Automatically coordinates brightness (LevelControl) and color (ColorControl)
if (
  extendedColorControlTrait.supports(
    ExtendedColorControl.Command.MoveToColorRgb
  )
) {
  extendedColorControlTrait.moveToColorRgb(
    red = 255u,
    green = 128u,
    blue = 0u
  )
}
val currentRed = extendedColorControlTrait.currentRed
val currentGreen = extendedColorControlTrait.currentGreen
val currentBlue = extendedColorControlTrait.currentBlue
// 3. Set color and brightness together using floating-point HSV
// hue: 0.0f..360.0f, saturation: 0.0f..1.0f, value (brightness): 0.0f..1.0f
if (
  extendedColorControlTrait.supports(
    ExtendedColorControl.Command.MoveToColorHsv
  )
) {
  extendedColorControlTrait.moveToColorHsv(
    hue = 210.0f,
    saturation = 0.85f,
    value = 0.75f
  )
}
val currentHue = extendedColorControlTrait.currentHue
val currentSaturation = extendedColorControlTrait.currentSaturation
val currentValue = extendedColorControlTrait.currentValue

管理光照曲线

光照曲线定义了一个自动化时间表,可在一天中平滑地转换目标灯具的亮度和可选色温。例如,照明曲线可以在早晨逐渐调亮灯光,在晚上将灯光调暗至更温暖的色调。仅支持亮度的灯具设备类型(例如可调光灯)会遵循亮度曲线,并忽略色温。

LightingCurve 特征是结构级 Google Home platform 特征。您可以通过 Structure 实例(而非单个照明设备)访问它。

此 trait 上的每个时间表都由一个 LightingCurveSetting 表示,它将唯一的 settingId 与 LightingCurveConfig 配对。下表介绍了 LightingCurveConfig 的配置字段:

字段 说明
curvePointsList 至少两个 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。
daysOfWeekList 照明曲线在每周内的哪些天运行 (DayOfWeek)。如果列表为空,则照明曲线每天运行。
adaptive 可选布尔值,用于指明光照曲线是否为自适应,即目标灯具在预约时限范围内开启时是否会恢复到有效曲线级别。如果设为 false,手动更改灯光设置后,灯光在当天剩余时间内将不再遵循光照曲线。如果设为 true,在预约时限内关闭并重新打开灯具后,灯具会重新应用照明曲线,使其符合曲线的当前亮度和色温,并从该点开始遵循曲线。
enabled 可选布尔值,用于指示光照曲线设置是否处于启用状态。创建新设置时,默认值为 true。如果更新命令中省略了 enabled,则 enabled 的状态不会更改。

读取光效曲线设置

如需检查为结构配置的光照曲线,请从 Structure 中检索 LightingCurve 特性,并读取其 lightingCurveSettingsList 属性。

suspend fun readLightingCurves(structure: Structure) {
  val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return

  for (setting in lightingCurve.lightingCurveSettingsList) {
    val settingId = setting.settingId
    val config = setting.config
    println("Setting ID: $settingId, enabled: ${config?.enabled}")
    config?.curvePointsList?.forEach { point ->
      println(
        "  Time: ${point.time?.hours}:${point.time?.minutes}, " +
          "Brightness: ${point.brightnessPercent}%, " +
          "ColorTemp: ${point.colorTemperature}K"
      )
    }
  }
}

创建光效曲线设置

如需在结构体上创建新的光照曲线时间表,请构建一个 LightingCurveConfig,其中至少包含两个 CurvePoint 条目、目标灯(由 roomId 或 devices 指定)以及一周中的有效日期。然后,将配置传递给 createLightingCurveSetting()。该命令会返回分配给新光照曲线设置的唯一 settingId。

以下示例为房间创建了工作日照明曲线。它在上午 7:00 时亮度为 30%,色温为 2700K(暖色),到上午 9:00 时亮度升至 80%,色温为 4000K(冷色),到晚上 9:00 时亮度降至 20%,色温为 2200K(极暖色):

suspend fun createRoomLightingCurve(
  structure: Structure,
  targetRoomId: String
): String? {
  val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return null

  val curvePoints = listOf(
    LightingCurveTrait.CurvePoint(
      time = LightingCurveTrait.CurveTimeOfDay(hours = 7, minutes = 0),
      brightnessPercent = 30,
      colorTemperature = 2700
    ),
    LightingCurveTrait.CurvePoint(
      time = LightingCurveTrait.CurveTimeOfDay(hours = 9, minutes = 0),
      brightnessPercent = 80,
      colorTemperature = 4000
    ),
    LightingCurveTrait.CurvePoint(
      time = LightingCurveTrait.CurveTimeOfDay(hours = 21, minutes = 0),
      brightnessPercent = 20,
      colorTemperature = 2200
    )
  )

  val config = LightingCurveTrait.LightingCurveConfig(
    curvePointsList = curvePoints,
    roomId = targetRoomId,
    daysOfWeekList = listOf(
      DayOfWeek.MONDAY,
      DayOfWeek.TUESDAY,
      DayOfWeek.WEDNESDAY,
      DayOfWeek.THURSDAY,
      DayOfWeek.FRIDAY
    ),
    adaptive = true,
    enabled = true
  )

  // Returns the newly created settingId
  return lightingCurve.createLightingCurveSetting(config = config)
}

如需定位到特定照明设备(而非整个房间),请使用 LightingCurveTrait.TargetDevices 提供 devices 参数:

val targetDevices = LightingCurveTrait.TargetDevices(
  devicesList = listOf(
    LightingCurveTrait.TargetDevice(
      id = dimmableLight.id.id,
      type = DimmableLightDevice.TYPE_ID
    )
  )
)

val deviceCurveConfig = LightingCurveTrait.LightingCurveConfig(
  curvePointsList = curvePoints,
  devices = targetDevices,
  daysOfWeekList = listOf(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY),
  adaptive = true,
  enabled = true
)

val settingId = lightingCurve.createLightingCurveSetting(
  config = deviceCurveConfig
)

更新光照曲线设置

如需修改现有光照曲线(例如更改其曲线点、更新一周中的有效日期,或启用和停用时间表),请使用目标 settingId 和更新后的 LightingCurveConfig 调用 updateLightingCurveSetting()。

suspend fun updateLightingCurve(
  structure: Structure,
  settingId: String,
  updatedConfig: LightingCurveTrait.LightingCurveConfig
) {
  val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return

  lightingCurve.updateLightingCurveSetting(
    settingId = settingId,
    config = updatedConfig
  )
}

删除光效曲线设置

如需从结构中移除光照曲线设置,请使用要删除的设置的 settingId 调用 deleteLightingCurveSetting()。

suspend fun deleteLightingCurve(
  structure: Structure,
  settingId: String
) {
  val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return

  lightingCurve.deleteLightingCurveSetting(settingId = settingId)
}