照明デバイスは、標準の Matter トレイトを使用して、照明器具の識別、電源状態の切り替え、明るさレベルの調整を行います。
最も基本的な照明デバイスタイプは OnOffLightDeviceType です。これは OnOffTrait トレイトと IdentifyTrait トレイトで実装され、必要に応じて LevelControlTrait トレイトと LightEffectsTrait トレイトをサポートします。
他のライトタイプは追加機能を提供し、異なるトレイトで実装されます。
| 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)
1 つのフィルタで、複数の照明デバイスタイプにわたるすべての照明デバイスを取得することもできます。
// 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!
照明デバイスを識別する
部屋に複数の照明がある場合、数秒間照明を点滅させるなど、視覚的な識別状態をトリガーすることで、ユーザーが特定の物理的な照明器具を見つけられるようにすることができます。4 つの照明デバイスタイプはすべて、Matter.IdentifyTrait トレイトを必要とします。
identify コマンドを identifyTime 期間(秒単位)で呼び出して、識別状態を開始します。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 の場合、ライトは消灯します。
ライトの電源状態を変更するには、トレイトが目的のコマンドをサポートしていることを確認してから、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 は必要に応じてサポートできます。このトレイトを使用して、ライトの明るさレベルを読み取り、制御します。
currentLevel 属性は、現在の明るさレベルを 0~254 のスケールで報告します。また、minLevel と maxLevel を検査して、ハードウェアでサポートされている有効な明るさの範囲を特定することもできます。
明るさを特定の値に設定するには、moveToLevel() を呼び出します。moveToLevel() は、optionsOverride を executeIfOff で構成しない限り、ライトがすでに点灯している場合にのみ現在のレベルを変更します。ゼロ以外の明るさレベルを設定するときにライトを自動的にオンにする(またはレベルを最小に設定するときにライトをオフにする)には、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 10 分の 1 秒)の遷移で調光可能なライトを 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 の両方で使用できます。このトレイトを使用すると、色温度をマイクロ逆数度(マイレッド)で調整できます。
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 値、または色と明るさを 1 つの単位にまとめた統合浮動小数点 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
照明曲線を管理する
照明曲線は、1 日を通してターゲット ライトの明るさとオプションの色温度をスムーズに移行する自動スケジュールを定義します。たとえば、照明曲線を使用すると、朝は照明を徐々に明るくし、夕方は暖色系のトーンに暗くすることができます。明るさのみをサポートする照明デバイスタイプ(調光可能ライトなど)は、明るさの曲線に従い、色温度を無視します。
Google.LightingCurveTrait トレイトは、ストラクチャ レベルの Google Home platform (GHP) トレイトです。個々の照明デバイスからではなく、Structure インスタンスからアクセスします。
トレイトの各スケジュールは LightingCurveSetting で表され、一意の settingId と LightingCurveConfig がペアになっています。次の表に、LightingCurveConfig の構成フィールドを示します。
| フィールド | 説明 |
|---|---|
curvePointsArray |
異なる時刻を持つ 2 つ以上の CurvePoint アイテムのシーケンス。各ポイントは、time(CurveTimeOfDay、hours は 0~23、minutes は 0~59)、brightnessPercent(0~100)、オプションの colorTemperature(ケルビン単位)を指定します。colorTemperature を指定する場合は、すべての地点で正の値にする必要があります。 |
roomId |
対象の部屋の ID(例: room@{uuid})。その部屋にある、対応する調光可能なライトと色温度ライトに照明曲線が適用されます。roomId または devices を指定します。 |
devices |
TargetDevice エントリのリストを含む TargetDevices オブジェクト。各エントリにはデバイス 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"
)
}
}
}
照明曲線設定を作成する
ストラクチャに新しい照明カーブ スケジュールを作成するには、少なくとも 2 つの CurvePoint エントリ、ターゲット ライト(roomId または devices で指定)、有効な曜日を含む LightingCurveConfig を作成します。次に、構成を createLightingCurveSetting() に渡します。このコマンドは、新しい照明曲線設定に割り当てられた一意の settingId を返します。
次の例では、平日の部屋の照明カーブを作成しています。午前 7 時に明るさを 30% から 80% に上げ、午後 9 時に 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)
}