Guida al dispositivo di illuminazione

I dispositivi di illuminazione utilizzano i tratti Matter standard per identificare gli apparecchi, attivare/disattivare gli stati di alimentazione e regolare i livelli di luminosità.

Il tipo di dispositivo di illuminazione più semplice è OnOffLightDeviceType, che viene implementato con i tratti OnOffTrait e IdentifyTrait e supporta facoltativamente i tratti LevelControlTrait e LightEffectsTrait.

Altri tipi di luci offrono funzionalità aggiuntive e vengono implementati con tratti diversi:

Tipo di dispositivo delle API Home Tratti App di esempio Swift Caso d'uso

Luce con temperatura di colore

ColorTemperatureLightDeviceType

home.matter.0000.types.010c

Un dispositivo di illuminazione che può essere acceso o spento e di cui è possibile regolare l'intensità della luce e la temperatura di colore.

Tratti richiesti
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait
     matter ColorControlTrait

Tratti facoltativi
     google LightEffectsTrait
     google ExtendedColorControlTrait
Chiaro

Luce dimmerabile

DimmableLightDeviceType

home.matter.0000.types.0101

Un dispositivo di illuminazione che può essere acceso o spento, la cui intensità della luce può essere regolata e che può essere attivato tramite un sensore di presenza associato.

Tratti richiesti
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait

Tratti facoltativi
     google LightEffectsTrait
Chiaro

Luce a gamma cromatica estesa

ExtendedColorLightDeviceType

home.matter.0000.types.010d

Un dispositivo di illuminazione che può essere acceso o spento, la cui intensità della luce e la temperatura di colore possono essere regolate e che può essere attivato tramite un sensore di presenza associato.

Tratti richiesti
     matter IdentifyTrait
     matter OnOffTrait
     matter LevelControlTrait
     matter ColorControlTrait

Tratti facoltativi
     google LightEffectsTrait
     google ExtendedColorControlTrait
Chiaro

Luce On/Off

OnOffLightDeviceType

home.matter.0000.types.0100

Un dispositivo di illuminazione che può essere acceso o spento.

Tratti obbligatori
     matter IdentifyTrait
     matter OnOffTrait

Tratti facoltativi
     matter LevelControlTrait
     google LightEffectsTrait
Chiaro

Controlla sempre il supporto di attributi e comandi per un dispositivo prima di utilizzare qualsiasi funzionalità o di tentare di aggiornare gli attributi. Per saperne di più, consulta Controlla i dispositivi su iOS.

Prerequisiti

Prima di utilizzare i dispositivi di illuminazione e le curve di illuminazione, assicurati che l'app inizializzi Home SDK e includa le importazioni richieste:

import Foundation
import GoogleHomeSDK
import GoogleHomeTypes
import Network

Trova i dispositivi di illuminazione

Per trovare i dispositivi di illuminazione in una struttura, filtra l'elenco dei dispositivi per tipo, ad esempio OnOffLightDeviceType e 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)

Puoi anche recuperare tutti i dispositivi di illuminazione di più tipi di dispositivi di illuminazione in un unico filtro:

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

Ricevi informazioni di base su un dispositivo

   Implementato nell'app di esempio per iOS   

Il tratto BasicInformation include informazioni come il nome del fornitore, l'ID fornitore, l'ID prodotto, il nome del prodotto (incluse le informazioni sul modello) e la versione software di un dispositivo:

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!

Identifica un dispositivo di illuminazione

Quando una stanza contiene più luci, puoi aiutare gli utenti a individuare un apparecchio fisico specifico attivando uno stato di identificazione visiva, ad esempio facendo lampeggiare la luce per alcuni secondi. Tutti e quattro i tipi di dispositivi luminosi richiedono il tratto Matter.IdentifyTrait.

Chiama il comando identify con una durata identifyTime in secondi per avviare lo stato di identificazione. Se passi 0, lo stato di identificazione viene interrotto immediatamente. Puoi anche chiamare triggerEffect per eseguire un effetto visivo specifico, come Blink o 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
    )
  }
}

Controllare la connettività di un dispositivo di illuminazione

La connettività di un dispositivo viene effettivamente controllata a livello di tipo di dispositivo, perché alcuni dispositivi supportano più tipi di dispositivi. Lo stato restituito è una combinazione degli stati di connettività per tutti i trait di quel dispositivo.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

In caso di tipi di dispositivi misti, potrebbe essere osservato uno stato di partiallyOnline quando non è presente una connessione a internet. I tratti standard Matter potrebbero essere ancora online grazie al routing locale, ma i tratti basati su cloud saranno offline.

Recupera l'indirizzo IP del dispositivo

Per trovare l'indirizzo IP del dispositivo, utilizza l'attributo networkInterfaces di GeneralDiagnosticsTrait. Gli indirizzi vengono restituiti come oggetti Data, che puoi formattare in stringhe IPv4 o IPv6 standard utilizzando il 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
}

Controlla i dispositivi di illuminazione

I tipi di dispositivi OnOffLight e DimmableLight utilizzano i tratti Matter standard per identificare gli impianti, attivare/disattivare gli stati di alimentazione e regolare i livelli di luminosità.

Accendere o spegnere una luce

Utilizza il tratto OnOffTrait per leggere lo stato di alimentazione corrente di un OnOffLight o DimmableLight e per accendere o spegnere la luce.

Prima di leggere l'attributo onOff, verifica che il dispositivo lo supporti. Alcuni dispositivi funzionano come endpoint di soli comandi e non segnalano lo stato.

// 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!")
}

Quando onOff è true, la spia è accesa. Quando onOff è false, la spia è spenta.

Per modificare lo stato di alimentazione della luce, verifica che il tratto supporti il comando previsto, quindi chiama on(), off() o 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
}

Puoi anche chiamare direttamente on() e off() per impostare uno stato esplicito:

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let _ as HomeError {
  // Code for handling the exception
}

Per spegnere una luce con una transizione visiva graduale, chiama offWithEffect() e specifica un valore 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
}

Regola la luminosità

Un DimmableLight richiede il tratto LevelControlTrait e un OnOffLight può supportarlo facoltativamente. Utilizza questo tratto per leggere e controllare il livello di luminosità di una luce.

L'attributo currentLevel indica il livello di luminosità attuale su una scala da 0 a 254. Puoi anche esaminare minLevel e maxLevel per determinare l'intervallo di luminosità valido supportato dall'hardware.

Per impostare la luminosità su un valore specifico, chiama moveToLevel(). Tieni presente che moveToLevel() modifica il livello corrente solo quando la luce è già accesa, a meno che non configuri optionsOverride con executeIfOff. Per accendere automaticamente la luce quando imposti un livello di luminosità diverso da zero (o per spegnerla quando imposti il livello al minimo), utilizza 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
}

L'esempio seguente legge il livello di luminosità corrente e utilizza moveToLevelWithOnOff() per impostare una luce dimmerabile su una luminosità del 75% (190) in una transizione di 1 secondo (10 decimi di secondo):

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

Puoi anche aumentare o diminuire la luminosità rispetto al livello corrente chiamando stepWithOnOff() con .up o .down e un stepSize.

Colore del controllo

Il tratto ColorControlTrait è disponibile sia su ColorTemperatureLightDeviceType sia su ExtendedColorLightDeviceType.

Questo tratto consente di regolare la temperatura di colore in gradi microreciproci o mired.

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

Puoi anche impostare il colore utilizzando le coordinate di cromaticità CIE 1931 e i valori di tonalità e saturazione a 16 bit.

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 è un trait Google facoltativo su ExtendedColorLightDevice che semplifica il controllo del colore accettando nomi di colori, valori RGB o valori HSV in rappresentazione in virgola mobile unificati che combinano colore e luminosità in un'unica unità.

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

Gestisci le curve di illuminazione

Una curva di illuminazione definisce una programmazione automatica che regola gradualmente la luminosità e la temperatura di colore facoltativa delle luci target nel corso della giornata. Ad esempio, una curva di illuminazione può aumentare gradualmente la luminosità delle luci al mattino e diminuirla fino a una tonalità più calda la sera. I tipi di dispositivi di illuminazione che supportano solo la luminosità, come la luce dimmerabile, seguono la curva di luminosità e ignorano la temperatura di colore.

Il tratto Google.LightingCurveTrait è un tratto Google Home platform (GHP) a livello di struttura. Puoi accedervi da un'istanza Structure anziché da un singolo dispositivo di illuminazione.

Ogni programmazione del tratto è rappresentata da un LightingCurveSetting, che associa un settingId univoco a un LightingCurveConfig. La tabella seguente descrive i campi di configurazione di LightingCurveConfig:

Campo Descrizione
curvePointsArray Una sequenza di almeno due elementi CurvePoint con orari distinti. Ogni punto specifica un time (CurveTimeOfDay con hours da 0 a 23 e minutes da 0 a 59), un brightnessPercent (da 0 a 100) e un colorTemperature facoltativo in Kelvin. Se colorTemperature è specificato per un punto, deve essere un valore positivo per tutti i punti.
roomId L'ID della stanza di destinazione (ad esempio, room@{uuid}). Applica la curva di illuminazione alle luci dimmerabili e con temperatura di colore compatibili in quella stanza. Specifica roomId o devices.
devices Un oggetto TargetDevices contenente un elenco di voci TargetDevice, ciascuna con un id dispositivo e un ID dispositivo type (ad esempio home.matter.0000.types.0101 per DimmableLight o home.matter.0000.types.010c per ColorTemperatureLight). Specifica devices o roomId.
daysOfWeekArray I giorni della settimana in cui viene eseguita la curva di illuminazione (Locale.Weekday). Se l'elenco è vuoto, la curva di illuminazione viene eseguita ogni giorno.
adaptive Valore booleano facoltativo che indica se la curva di illuminazione è adattiva, ovvero se una luce target riprende il livello della curva attiva quando viene accesa durante la finestra di programmazione. Quando false, una modifica manuale di una luce la disattiva dalla curva di illuminazione per il resto della giornata. Quando true, una luce che viene spenta e poi riaccesa durante la finestra di programmazione si ricollega alla curva di illuminazione, adattandosi alla luminosità e alla temperatura di colore attuali della curva e seguendola da quel momento in poi.
enabled Valore booleano facoltativo che indica se l'impostazione della curva di illuminazione è attiva. Il valore predefinito è true quando crei una nuova impostazione. Quando enabled viene omesso da un comando di aggiornamento, lo stato di enabled non cambia.

Lettura delle impostazioni della curva di illuminazione

Per esaminare le curve di illuminazione configurate per una struttura, recupera il tratto Google.LightingCurveTrait da Structure e leggi il relativo attributo 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"
      )
    }
  }
}

Crea un'impostazione della curva di illuminazione

Per creare una nuova programmazione della curva di illuminazione su una struttura, crea un LightingCurveConfig con almeno due voci CurvePoint, luci target (specificate da roomId o devices) e i giorni della settimana attivi. Poi, passa la configurazione a createLightingCurveSetting(). Il comando restituisce l'identificatore univoco settingId assegnato alla nuova impostazione della curva di illuminazione.

L'esempio seguente crea una curva di illuminazione per i giorni feriali per una stanza che aumenta la luminosità dal 30% alle 07:00 all'80% alle 09:00 e la riduce al 20% alle 21:00:

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
}

Per scegliere come target dispositivi di illuminazione specifici anziché un'intera stanza, fornisci il parametro devices utilizzando Google.LightingCurveTrait.TargetDevices:

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

Aggiorna un'impostazione della curva di illuminazione

Per modificare una curva di illuminazione esistente, ad esempio modificando i punti della curva, aggiornando i giorni della settimana attivi o attivando e disattivando la programmazione, chiama updateLightingCurveSetting() con il settingId target e un LightingCurveConfig aggiornato.

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

Elimina un'impostazione della curva di illuminazione

Per rimuovere un'impostazione della curva di illuminazione da una struttura, chiama deleteLightingCurveSetting() con il settingId dell'impostazione che vuoi eliminare.

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