Los dispositivos de iluminación usan los atributos estándar de Matter para identificar las lámparas, activar o desactivar los estados de encendido y ajustar los niveles de brillo.
El tipo de dispositivo de luz más básico es OnOffLight, que se implementa con los atributos OnOff y Identify, y, de manera opcional, admite los atributos LevelControl y LightEffects.
Otros tipos de luces ofrecen capacidades adicionales y se implementan con diferentes rasgos:
| Tipo de dispositivo de las APIs de Home | Rasgos | App de ejemplo de Kotlin | Caso de uso |
|---|---|---|---|
|
Luz de temperatura de color
Un dispositivo de iluminación que se puede encender o apagar, y cuya intensidad de luz y temperatura de color se pueden ajustar. |
Atributos obligatorios matter Identify matter OnOff matter LevelControl matter ColorControl |
encendido y apagado, brillo |
Ligera |
|
Luz regulable
Es un dispositivo de iluminación que se puede encender o apagar, cuya intensidad de luz se puede ajustar y que se puede encender o apagar a través de un sensor de ocupación vinculado. |
Atributos obligatorios matter Identify matter OnOff matter LevelControl |
encendido y apagado, brillo |
Ligera |
|
Luz de color extendida
Es un dispositivo de iluminación que se puede encender o apagar, cuya intensidad de luz y temperatura de color se pueden ajustar, y que se puede encender o apagar a través de un sensor de ocupación vinculado. |
Atributos obligatorios matter Identify matter OnOff matter LevelControl matter ColorControl |
encendido y apagado, brillo |
Ligera |
|
Luz de encendido/apagado
Un dispositivo de iluminación que se puede encender o apagar. |
Atributos obligatorios matter Identify matter OnOff |
encendido y apagado, brillo |
Ligera |
Siempre verifica la compatibilidad de atributos y comandos de un dispositivo antes de usar cualquier función o intentar actualizar los atributos. Consulta Controla dispositivos en Android para obtener más información.
Requisitos previos
Antes de trabajar con dispositivos y curvas de iluminación, asegúrate de que tu app inicialice el SDK de Home y de que incluya las importaciones requeridas:
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
Buscar dispositivos de iluminación
Para encontrar dispositivos de iluminación en una estructura, filtra la lista de dispositivos por tipo, como OnOffLightDevice y 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()
También puedes recuperar todos los dispositivos de iluminación de varios tipos de dispositivos de iluminación en un solo filtro:
// 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) } }
Obtén información básica sobre un dispositivo
Implementado en la app de ejemplo para Android
El atributo BasicInformation
incluye información como el nombre del proveedor, el ID del proveedor, el ID del producto,
el nombre del producto (incluye información del modelo) y la versión de software de un dispositivo:
// 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}") }
Identifica un dispositivo de iluminación
Cuando una habitación contiene varias luces, puedes ayudar a los usuarios a ubicar una lámpara física específica activando un estado de identificación visual, como hacer parpadear la luz durante unos segundos. Los cuatro tipos de dispositivos de iluminación requieren el atributo Identify.
Llama al comando identify con una duración de identifyTime en segundos para iniciar
el estado de identificación. Si pasas 0, se detiene el estado de identificación de inmediato. También puedes llamar a triggerEffect para ejecutar un efecto visual específico, como Blink o 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
)
}
}
Verifica la conectividad de un dispositivo de iluminación
La conectividad de un dispositivo se verifica a nivel del tipo de dispositivo, ya que algunos dispositivos admiten varios tipos. El estado que se devuelve es una combinación de los estados de conectividad de todos los rasgos de ese dispositivo.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Se puede observar un estado de partiallyOnline en el caso de tipos de dispositivos mixtos
cuando no hay conectividad a Internet. Es posible que los atributos estándar de Matter sigan en línea debido al enrutamiento local, pero los atributos basados en la nube estarán sin conexión.
Obtén la dirección IP del dispositivo
Para encontrar la dirección IP del dispositivo, usa el atributo networkInterfaces de
GeneralDiagnosticsTrait.
Las direcciones se devuelven como objetos Data, a los que puedes dar formato de
strings IPv4 o IPv6 estándar con el framework Network:
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
}
Cómo controlar dispositivos de iluminación
Los tipos de dispositivos OnOffLight y DimmableLight usan rasgos estándar de Matter para identificar artefactos, activar o desactivar estados de energía y ajustar los niveles de brillo.
Encender o apagar una luz
Usa el atributo OnOff para leer el estado de alimentación actual de un OnOffLight o DimmableLight, y para encender o apagar la luz.
Antes de leer el atributo onOff, verifica que el dispositivo lo admita. Algunos
dispositivos funcionan como extremos de solo comando y no informan el estado.
// 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!") }
Cuando onOff es true, la luz está encendida. Cuando onOff es false, la luz está apagada.
Para cambiar el estado de encendido de la luz, verifica que el rasgo admita el comando previsto y, luego, llama a on(), off() o 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 }
También puedes llamar a on() y off() directamente para establecer un estado explícito:
onOffTrait.off() onOffTrait.on()
Para apagar una luz con una transición visual gradual, llama a offWithEffect() y especifica un valor de EffectIdentifierEnum:
// Turn off the light using the DyingLight effect. onOffTrait.offWithEffect( effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight, effectVariant = 0u, )
Ajustar los niveles de brillo
Un DimmableLight requiere el atributo LevelControl, y un OnOffLight puede admitirlo de manera opcional. Usa este atributo para leer y
controlar el nivel de brillo de una luz.
El atributo currentLevel informa el nivel de brillo actual en una escala de 0 a 254. También puedes inspeccionar minLevel y maxLevel para determinar el rango de brillo válido que admite el hardware.
Para establecer el brillo en un valor específico, llama a moveToLevel(). Ten en cuenta que moveToLevel() solo cambia el nivel actual cuando la luz ya está encendida, a menos que configures optionsOverride con executeIfOff. Para encender la luz automáticamente cuando se establece un nivel de brillo distinto de cero (o apagarla cuando se establece el nivel mínimo), usa moveToLevelWithOnOff().
// Change the brightness of the light to 50% levelControlTrait.moveToLevel( level = 127u.toUByte(), transitionTime = null, optionsMask = LevelControlTrait.OptionsBitmap(), optionsOverride = LevelControlTrait.OptionsBitmap(), )
En el siguiente ejemplo, se lee el nivel de brillo actual y se usa moveToLevelWithOnOff() para establecer una luz regulable en un 75% de brillo (190u) durante una transición de 1 segundo (10u décimas de segundo):
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() ) } }
También puedes aumentar o disminuir el brillo en relación con el nivel actual llamando a stepWithOnOff() con StepModeEnum.Up o StepModeEnum.Down y un stepSize.
Controla el color
El atributoColorControl está disponible en ColorTemperatureLightDevice y ExtendedColorLightDevice.
Este atributo te permite ajustar la temperatura de color en grados microrecíprocos o mireds.
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() ) }
También puedes establecer el color con las coordenadas de cromaticidad CIE 1931 y los valores de tono y saturación de 16 bits.
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
es un atributo opcional de Google en
ExtendedColorLightDevice
que simplifica el control de color, ya que acepta nombres de colores, valores RGB o valores HSV
unificados de punto flotante que combinan el color y el brillo en una sola unidad.
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
Administra las curvas de iluminación
Una curva de iluminación define un programa automatizado que realiza una transición fluida del brillo y la temperatura de color opcional de las luces de destino durante el día. Por ejemplo, una curva de iluminación puede aumentar gradualmente el brillo de las luces por la mañana y atenuarlas a un tono más cálido por la noche. Los tipos de dispositivos de iluminación que solo admiten el brillo, como la luz regulable, siguen la curva de brillo y, además, ignoran la temperatura de color.
El atributo LightingCurve es un atributo Google Home platform a nivel de la estructura. Se accede a él
desde una instancia de Structure,
en lugar de un dispositivo de iluminación individual.
Cada programa del atributo se representa con un LightingCurveSetting, que vincula un settingId único con un LightingCurveConfig. En la siguiente tabla,
se describen los campos de configuración de LightingCurveConfig:
| Campo | Descripción |
|---|---|
curvePointsList |
Es una secuencia de, al menos, dos elementos CurvePoint con horas distintas. Cada punto especifica un time (CurveTimeOfDay con hours de 0 a 23 y minutes de 0 a 59), un brightnessPercent (de 0 a 100) y un colorTemperature opcional en Kelvin. Si se especifica colorTemperature para cualquier punto, debe ser un valor positivo para todos los puntos. |
roomId |
Es el ID de la habitación de destino (por ejemplo, room@{uuid}). Aplica la curva de iluminación a las luces compatibles con atenuación y temperatura de color de esa habitación. Especifica roomId o devices. |
devices |
Un objeto TargetDevices que contiene una lista de entradas TargetDevice, cada una con un id de dispositivo y un ID de type de dispositivo (como home.matter.0000.types.0101 para DimmableLight o home.matter.0000.types.010c para ColorTemperatureLight). Especifica devices o roomId. |
daysOfWeekList |
Son los días de la semana en los que se ejecuta la curva de iluminación (DayOfWeek). Si la lista está vacía, la curva de iluminación se ejecuta a diario. |
adaptive |
Es un valor booleano opcional que indica si la curva de iluminación es adaptable, lo que significa que una luz de destino reanuda el nivel de curva activo cuando se enciende durante el plazo programado. Cuando se establece en false, un cambio manual en una luz la desvincula de la curva de iluminación durante el resto del día. Cuando true, una luz que se apaga y se vuelve a encender durante el período de programación se vuelve a activar con la curva de iluminación, lo que hace que se ajuste al brillo y la temperatura de color actuales de la curva, y que siga la curva a partir de ese momento. |
enabled |
Es un valor booleano opcional que indica si el parámetro de configuración de la curva de iluminación está activo. El valor predeterminado es true cuando se crea un parámetro de configuración nuevo. Cuando se omite enabled de un comando de actualización, el estado de enabled no cambia. |
Cómo leer la configuración de la curva de iluminación
Para inspeccionar las curvas de iluminación configuradas para una estructura, recupera el atributo LightingCurve de Structure y lee su atributo 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"
)
}
}
}
Crea un parámetro de configuración de curva de iluminación
Para crear un programa de curva de iluminación nuevo en una estructura, construye un
LightingCurveConfig con al menos dos entradas CurvePoint, luces de destino
(especificadas por roomId o devices) y los días activos de la semana. Luego,
pasa la configuración a createLightingCurveSetting(). El comando devuelve
el settingId único asignado al nuevo parámetro de configuración de la curva de iluminación.
En el siguiente ejemplo, se crea una curva de iluminación para los días de semana en una habitación. Aumenta del 30% de brillo con una temperatura cálida de 2,700 K a las 7:00 a.m. al 80% con una temperatura más fría de 4,000 K a las 9:00 a.m. Luego, se atenúa al 20% con una temperatura muy cálida de 2,200 K a las 9:00 p.m.:
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)
}
Para segmentar dispositivos de iluminación específicos en lugar de una habitación completa, proporciona el parámetro devices con LightingCurveTrait.TargetDevices:
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
)
Actualiza un parámetro de configuración de la curva de iluminación
Para modificar una curva de iluminación existente, como cambiar sus puntos de curva, actualizar los días activos de la semana o habilitar e inhabilitar el programa, llama a updateLightingCurveSetting() con el settingId de destino y un LightingCurveConfig actualizado.
suspend fun updateLightingCurve(
structure: Structure,
settingId: String,
updatedConfig: LightingCurveTrait.LightingCurveConfig
) {
val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return
lightingCurve.updateLightingCurveSetting(
settingId = settingId,
config = updatedConfig
)
}
Borra un parámetro de configuración de curva de iluminación
Para quitar un parámetro de configuración de la curva de iluminación de una estructura, llama a deleteLightingCurveSetting() con el settingId del parámetro de configuración que deseas borrar.
suspend fun deleteLightingCurve(
structure: Structure,
settingId: String
) {
val lightingCurve = structure.trait(LightingCurve).firstOrNull() ?: return
lightingCurve.deleteLightingCurveSetting(settingId = settingId)
}