iOS 上的自动化操作示例

以下是一些自动化操作示例,旨在展示可使用 Automation API 自动执行的各种不同任务,或许还能为您带来更多想法。

在其他设备开启或关闭时开启设备

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait

...

let starterNode = starter(device1, OnOffLightDeviceType.self, OnOffTrait.self)
let device2State = stateReader(device2, OnOffLightDeviceType.self, OnOffTrait.self

automation (
  name: "Turn on a device",
  description:
    """
    Turn on a device when another device is turned on or off
    """
) {
 starterNode
 device2State
 condition {
   // Only send the command if device2 is off
   device2State.onOff.equals(false)
 }
 // Turn on device 2
 action(device2, OnOffLightDeviceType.self) {
   OnOffTrait.on()
 }
}

当室外温度低于 60 华氏度且外面天黑时,自动关闭百叶窗

import GoogleHomeSDK
import GoogleHomeTypes

typealias TemperatureMeasurementTrait = Matter.TemperatureMeasurementTrait
typealias TimeTrait = Google.TimeTrait
typealias WindowCoveringTrait = Matter.WindowCoveringTrait

let temperatureMeasurement = stateReader(
  thermostatDevice,
  TemperatureSensorDeviceType.self,
  TemperatureMeasurementTrait.self
)
let time = stateReader(structure, TimeTrait.self)

automation (
  name: "Close window blinds",
  description:
    """
    Automatically close window blinds when the temperature outside drops below 60F and it's dark
    outside.
    """
) {
  select {
    starter(
      eveThermostat,
      TemperatureSensorDeviceType.self,
      TemperatureMeasurementTrait.self
    )
    starter(structure, TimeTrait.ScheduledEvent.self) {
      TimeTrait.ScheduledEvent.solarTime(SolarTime(type: .sunrise, offset: .seconds(0)))
    }
    starter(structure, TimeTrait.ScheduledEvent.self) {
      TimeTrait.ScheduledEvent.solarTime(SolarTime(type: .sunset, offset: .seconds(0)))
    }
  }
  temperatureMeasurement
  time
  let exp1 = temperatureMeasurement.measuredValue.lessThan(1555)  // 15 degrees C ~ 60 degrees F
  let exp2 =
    localTimeBetweenCondition != nil
    ? time.currentTime.between(localTimeBetweenCondition!.0, localTimeBetweenCondition!.1)
    : time.currentTime.between(time.sunriseTime, time.sunsetTime)
  condition {
    exp1.and(exp2.not())
  }
  parallel {
    for windowBlind in windowBlinds {
      action(windowBlind, WindowCoveringDeviceType.self) {
        WindowCoveringTrait.downOrClose()
      }
    }
  }
}

如果车库门未关闭超过 10 分钟,向家庭成员的手机发送通知,并广播关闭车库门的提醒

import GoogleHomeSDK
import GoogleHomeTypes

typealias BooleanStateTrait = Matter.BooleanStateTrait

automation (
  name: "Broadcast reminder"
  description:
    """
    If garage door left open for more than 10 minutes,
    send a notification to household members phones
    and broadcast a reminder to close the garage door
    """
  )
{
    let garageSensorStarter = starter(
      garageDoorSensor,
      ContactSensorDeviceType.self,
      BooleanStateTrait.self
    )
    garageSensorStarter
    condition(
      for: .seconds(10 * 60)  // 10 minutes.
    ) {
      // stateValue - True means garage door is closed, False means open
      garageSensorStarter.stateValue.equals(false)
    }
    action(structure) {
      Google.AssistantBroadcastTrait.broadcast(msg: "Garage is open")
    }
    action(structure) {
      Google.NotificationTrait.sendNotifications(
        title: "Garage is open", body: nil, optInMemberEmailsArray: [])
    }
  }
}

当车库门打开时,开启门廊灯和车道灯

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait
typealias BooleanStateTrait = Matter.BooleanStateTrait

automation (
  name: "Turn on lights"
  description:
    """
    When the garage door opens, turn on porch and driveway lights
    """
) {
  let garageSensorStarter = starter(
    garageDoorSensor,
    ContactSensorDeviceType.self,
    BooleanStateTrait.self
  )
  garageSensorStarter
  condition {
    // stateValue - True means garage door is closed, False means open
    garageSensorStarter.stateValue.equals(false)
  }
  parallel {
    for light in drivewayLights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.on()
      }
    }
    for light in porchLights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.on()
      }
    }
  }
}

如果电视在烤箱周期结束时处于开启状态,客厅灯会闪烁,智能音箱会广播“烤箱周期已完成”

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait
typealias OperationalStateTrait = Matter.OperationalStateTrait

automation (
  name: "Broadcast oven cycle complete"
  description:
    """
    If TV is on when oven cycle completes,
    living room lights blink and smart speaker broadcasts \"Oven Cycle Complete\"
    """
) {
  let ovenCompletedEvent = starter(
    oven,
    OvenDeviceType.self,
    OvenCavityOperationalStateTrait.OperationCompletionEvent.self
  )
  ovenCompletedEvent
  condition {
    ovenCompletedEvent
      .completionErrorCode
      .equals(0x00)  // no error
  }

  let operationalState = stateReader(
    oven,
    OvenDeviceType.self,
    OvenCavityOperationalStateTrait.self
  )
  operationalState
  condition {
    operationalState.phaseList[operationalState.currentPhase.toUInt()].equals("pre-heated")
  }

  let tvOnOff = stateReader(
    tv,
    GoogleTVDeviceType.self,
    OnOffTrait.self
  )
  tvOnOff
  condition {
    tvOnOff.onOff.equals(true)
  }

  parallel {
    for speaker in speakers {
      action(speaker, SpeakerDeviceType.self) {
        Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
      }
    }
    for light in lights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.toggle()
      }
    }
  }
  delay(for: .seconds(30))
  parallel {
    for light in lights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.toggle()
      }
    }
  }
}

晚上 9 点,如果有人在家,电视会关闭,儿童卧室的灯会调暗,空调会调到特定温度

import GoogleHomeSDK
import GoogleHomeTypes
typealias OnOffTrait = Matter.OnOffTrait
typealias ThermostatTrait = Matter.ThermostatTrait

automation(
  name: "Turn AC on",
  description:
    """
    At 9pm, if someone is home, TV turns off, kids' bedroom lights dim,
    GE AC turns to [X#] degrees
    """
) {
  let timeStarter = starter(
    structure,
    Google.TimeTrait.ScheduledEvent.self
  ) {
    Google.TimeTrait.ScheduledEvent.clockTime(scheduledTime)
  }

  let stateReaderNode = stateReader(
    structure,
    Google.AreaPresenceStateTrait.self
  )
  timeStarter
  stateReaderNode
  condition {
    stateReaderNode
      .presenceState
      .equals(Google.AreaPresenceStateTrait.PresenceState.presenceStateOccupied)
  }
  parallel {
    action(tv, GoogleTVDeviceType.self) {
      OnOffTrait.off()
    }

    for light in kidBedroomLights {
      action(light, DimmableLightDeviceType.self) {
        LevelControlTrait.moveToLevel(
          level: dimmedLightLevel,
          transitionTime: 10,
          optionsMask: LevelControlTrait.OptionsBitmap(),
          optionsOverride: LevelControlTrait.OptionsBitmap()
        )
      }
    }
    let fahrenheit = Measurement(value: acTempInFahrenheit, unit: UnitTemperature.fahrenheit)
    let setpoint = Int16(fahrenheit.converted(to: .celsius).value)
    action(geAc, RoomAirConditionerDeviceType.self) {
      update(ThermostatTrait.self) {
        $0.setOccupiedCoolingSetpoint(setpoint * 100)
      }
    }
  }
}

在洗衣机洗衣周期结束时,在卧室音箱上播报“洗衣已完成”

import GoogleHomeSDK
import GoogleHomeTypes

typealias OperationalStateTrait = Matter.OperationalStateTrait

automation(
  name: "Broadcast laundry is done",
  description:
    """
    Announce \"laundry is done\" on bedroom speakers when the laundry machine cycle completes
    """
) {
  let laundryWasherCompletionEvent = starter(
    laundryWasher,
    LaundryWasherDeviceType.self,
    OperationalStateTrait.OperationCompletionEvent.self
  )
  laundryWasherCompletionEvent
  condition {
    laundryWasherCompletionEvent
      .completionErrorCode
      .equals(0x00)
  }

  action(bedroomSpeaker, SpeakerDeviceType.self) {
    Google.AssistantBroadcastTrait.broadcast(msg: "laundry is done")
  }
}

到家:如果 Aqara 锁已解锁且太阳落山后,天花板灯会亮起,3P 温控器设置会更新为 26 度,智能插座会重启电源,电视和咖啡机会开启。智能音箱说“欢迎回家!”

import GoogleHomeSDK
import GoogleHomeTypes

typealias DoorLockTrait = Matter.DoorLockTrait
typealias ThermostatTrait = Matter.ThermostatTrait

automation(
  name: "Door unlock turn on appliances",
  description:
    """
    Home Arrival: If Aqara lock is unlocked and it is after sunset,
    ceiling light turns on,
    update the 3P thermostat setting to 26 degress, smart plugs restart power, TV and coffeemaker
    turn on. Smart speaker says \"Welcome Home!\"
     """
) {
  let doorLockEvent = starter(
    doorLock, DoorLockDeviceType.self,
    DoorLockTrait.LockOperationEvent.self
  )
  let doorIsUnlocked = doorLockEvent.lockOperationType.equals(.unlock)

  let timeCondition =
    localTimeBetweenCondition != nil
    ? time.currentTime.between(localTimeBetweenCondition!.0, localTimeBetweenCondition!.1)
    : time.currentTime.between(time.sunsetTime, time.sunriseTime)

  time
  doorLockEvent
  condition {
    doorIsUnlocked.and(timeCondition)
  }

  parallel {
    for light in allLights {
      action(light, DimmableLightDeviceType.self) {
        OnOffTrait.on()
      }
    }

    action(thermostat, ThermostatDeviceType.self) {
      update(ThermostatTrait.self) {
        $0.setOccupiedCoolingSetpoint(2600)
      }
    }
    action(plug, OnOffPluginUnitDeviceType.self) {
      OnOffTrait.on()
    }
    action(tv, GoogleTVDeviceType.self) {
      OnOffTrait.on()
    }
    action(coffeemaker, CooktopDeviceType.self) {
      OnOffTrait.on()
    }
    action(structure) {
      Google.AssistantBroadcastTrait.broadcast(msg: "Welcome Home!")
    }
  }
}

用户可以创建“新鲜空气模式”日常活动,用于启动吊扇和吸尘器

import GoogleHomeSDK
import GoogleHomeTypes

typealias FanControlTrait = Matter.FanControlTrait

automation(
  name: "Fan and vaccum turn on",
  description:
    """
    User can create "Fresh Air Mode" routine which starts the ceiling fan,
    and vacuum
    """
) {
  manualStarter()

  parallel {
    action(fan, FanDeviceType.self) {
      update(FanControlTrait.self) {
        $0.setFanMode(.on)
      }
    }
    action(vacuum, RoboticVacuumCleanerDeviceType.self) {

      // 0 - idle, 1 - cleaning, 2 - mapping
      RvcRunModeTrait.changeToMode(newMode: 1)
    }
  }
}

当用户开启卧室灯且时间在晚上 9 点之后时,卧室灯泡会调整为暖色以放松身心,3 米长的遮光窗帘会关闭,分体式空调会调低 2 度以冷却房间。Google Nest Audio 播放“雨声”。

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait
typealias WindowCoveringTrait = Matter.WindowCoveringTrait

automation(
  name: "Bulbs warm color after 9pm",
  description:
    """
    When user turns on bedroom lights, and the time is after 9p, bedroom bulb adjusts
    to warm color to relax, 3P shades close,mini-split air conditioner adjusts
    down 2 degrees to cool the room. Google Nest Audio plays 'rain sounds'.
    """
) {
  select {
    for light in bedroomLights {
      let lightOnOffState = starter(
        light,
        OnOffLightDeviceType.self,
        OnOffTrait.self
      )
      lightOnOffState
      condition { lightOnOffState.onOff.equals(true) }
    }
  }
  let time = stateReader(structure, Google.TimeTrait.self)
  time
  condition {
    time.currentTime.between(
      betweenConditionTime.0,
      betweenConditionTime.1
    )
  }
  parallel {
    for light in colorControlBedroomLights {
      action(light, ColorTemperatureLightDeviceType.self) {
        ColorControlTrait.moveToColorTemperature(
          colorTemperatureMireds: 200,
          transitionTime: 10,
          optionsMask: 0,
          optionsOverride: 0
        )
      }
    }
    action(windowBlind, WindowCoveringDeviceType.self) {
      WindowCoveringTrait.downOrClose()
    }
    action(thermostatDevice, RoomAirConditionerDeviceType.self) {
      ThermostatTrait.setpointRaiseLower(
        mode: .cool,
        amount: 2
      )
    }
    action(speaker, SpeakerDeviceType.self) {
      Google.AssistantFulfillmentTrait.okGoogle(query: "Play rain sound.")
    }
  }
}

在您解锁门锁时开灯或关闭温控器节能模式。

import GoogleHomeSDK
import GoogleHomeTypes

typealias DoorLockTrait = Matter.DoorLockTrait
typealias OnOffTrait = Matter.OnOffTrait
typealias ThermostatTrait = Matter.ThermostatTrait

 automation(
  name: "Unlock door, turn on lights or turn off thermostat",
  description:
    """
    Turn on lights or turn off thermostat eco mode when you unlock the door.
    """
) {
  let doorLockEvent = starter(
    doorLock,
    DoorLockDeviceType.self,
    DoorLockTrait.LockOperationEvent.self
  )
  doorLockEvent
  condition {
    doorLockEvent.lockOperationType.equals(.unlock)
  }
  parallel {
    for light in allLights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.on()
      }
      // Assume the thermostat is in eco mode, set to auto.
      action(thermostat, ThermostatDeviceType.self) {
        Google.SimplifiedThermostatTrait.setSystemMode(systemMode: .auto)
       }
    }
  }
}

晚上 9 点锁门

import GoogleHomeSDK
import GoogleHomeTypes

typealias DoorLockTrait = Matter.DoorLockTrait

automation(
  name: "Lock the door",
  description: "At 9pm lock the door."
) {
  starter(structure, Google.TimeTrait.ScheduledEvent.self) {
    Google.TimeTrait.ScheduledEvent.clockTime(startTime)
  }
  action(doorLock, DoorLockDeviceType.self) {
    DoorLockTrait.lockDoor()
  }
}

当所有人都不在住宅时,关闭灯具。

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait

automation(
  name: "Turn off light",
  description: "When everyone is away from home, turn off lights."
) {
  let homeAwayState = starter(structure, Google.AreaPresenceStateTrait.self)
  homeAwayState
  condition {
    homeAwayState.presenceState.equals(.presenceStateVacant)
  }

  parallel {
    for light in allLights {
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
  }
}

如果检测到动作(传感器),在智能音箱上播放警报声音,定期开关灯和电视,以吓退入侵者。

import GoogleHomeSDK
import GoogleHomeTypes

typealias OccupancySensingTrait = Matter.OccupancySensingTrait
typealias OnOffTrait = Matter.OnOffTrait

automation(
  name: "Motion sensed, turn lights on and off to deter intruders",
  description:
    """
    If motion (sensor) is detected, broadcast alarm sound on smart speakers,
    turn lights on and off periodically and TV to deter intruders.
    """
) {
  let motionStarter =
    starter(motionSensor, OccupancySensorDeviceType.self, OccupancySensingTrait.self)
  let homeAwayState = stateReader(structure, Google.AreaPresenceStateTrait.self)
  motionStarter
  homeAwayState

  let exp1 = homeAwayState.presenceState.equals(.presenceStateVacant)
  let exp2 = motionStarter.occupancy.equals(.occupied)

  condition {
    exp1.and(exp2)
  }

  action(structure) {
    Google.AssistantBroadcastTrait.broadcast(msg: "ALARM! ALARM! ALARM!")
  }

  turnOnOff(lights: allLights, tv: tv, shouldTurnOn: true)
  delay(for: Duration.seconds(5))
  turnOnOff(lights: allLights, tv: tv, shouldTurnOn: false)
  delay(for: Duration.seconds(5))
  turnOnOff(lights: allLights, tv: tv, shouldTurnOn: true)
}

private func turnOnOff(
  lights: Set<HomeDevice>,
  tv: HomeDevice,
  shouldTurnOn: Bool
) -> ParallelFlow {
  parallel {
    for light in lights {
      action(light, OnOffLightDeviceType.self) {
        shouldTurnOn ? OnOffTrait.on() : OnOffTrait.off()
      }
    }
    action(tv, GoogleTVDeviceType.self) {
      shouldTurnOn ? OnOffTrait.on() : OnOffTrait.off()
    }
  }
}

卧室里的灯。如果晚上 10 点之后,用户关闭了灯,则所有房间灯都会关闭,窗帘会关闭,前门会锁定(非物理锁定)。

import GoogleHomeSDK
import GoogleHomeTypes

typealias WindowCoveringTrait = Matter.WindowCoveringTrait
typealias OnOffTrait = Matter.OnOffTrait
typealias DoorLockTrait = Matter.DoorLockTrait

automation(
  name: "After 10pm, turn all lights off, close shades, lock front door",
  description:
    """
    User has Lamp in their bedroom. If it is after 10pm and the user turns off the lamp,
    then all room lights turn off, shades close, front door locks (non-matter lock).
    """
) {
  let lampOnOffState = starter(Lamp, DimmableLightDeviceType.self, OnOffTrait.self)
  let time = stateReader(structure, Google.TimeTrait.self)
  lampOnOffState
  time
  let expr1 = lampOnOffState.onOff.equals(false)
  let expr2 = time.currentTime.between(
    localTimeBetweenCondition.0,
    localTimeBetweenCondition.1
  )

  condition {
    expr1.and(expr2)
  }

  parallel {
    for light in allLights {
      action(light, DimmableLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
    action(windowBlind, WindowCoveringDeviceType.self) {
      WindowCoveringTrait.downOrClose()
    }
    action(doorLock, DoorLockDeviceType.self) {
      DoorLockTrait.lockDoor()
    }
  }
}

如果用户说“Hey Google,我睡不着”,系统会播放海浪声,打开风扇,开启室内插座,并放下第三方遮阳篷

import GoogleHomeSDK
import GoogleHomeTypes

typealias FanControlTrait = Matter.FanControlTrait
typealias OnOffTrait = Matter.OnOffTrait
typealias WindowCoveringTrait = Matter.WindowCoveringTrait

automation(
  name: "Turn sleep sound, fan, indoor plug on",
  description:
    """
    If user says "Hey Google, I can't sleep",
    play ocean wave sounds, turn on the Fan,
    Indoor Plug turns on, and 3P shades roll down
    """
) {
  starter(structure, Google.VoiceStarterTrait.OkGoogleEvent.self) {
    Google.VoiceStarterTrait.OkGoogleEvent.query("I can't sleep")
  }
  parallel {
    action(speaker, SpeakerDeviceType.self) {
      Google.AssistantFulfillmentTrait.okGoogle(query: "Play ocean wave sounds")
    }
    action(fan, FanDeviceType.self) {
      update(FanControlTrait.self) {
        $0.setFanMode(.on)
      }
    }
    action(plug, OnOffPluginUnitDeviceType.self) {
      OnOffTrait.on()
    }
    action(shades, WindowCoveringDeviceType.self) {
      WindowCoveringTrait.downOrClose()
    }
  }
}

如果在家/外出传感器或在家/外出感应器检测到客厅无人,则风扇关闭,空调进入节能模式,并启动扫地机器人(每天最多一次)

import GoogleHomeSDK
import GoogleHomeTypes

typealias OccupancySensingTrait = Matter.OccupancySensingTrait
typealias FanControlTrait = Matter.FanControlTrait

{

  let time = stateReader(structure, Google.TimeTrait.self)
  let timeCondition: TypedExpression<Bool>

  if let localTimeBetweenCondition {
    timeCondition = time.currentTime.between(
      localTimeBetweenCondition.0,
      localTimeBetweenCondition.1
    )
  } else {
    timeCondition = time.currentTime.between(time.sunriseTime, time.sunsetTime)
  }
  return automation(
    name: "No motion detected, turn off fan and turn on vacuum",
    description:
      """
      If presence/occupancy sensor detects that the living room is empty, fan turns off,
      AC goes into Eco mode and robot vacuum starts (max once per day)
      """
  ) {


{
    let occupancySensorStarter = starter(
      occupancySensor,
      OccupancySensorDeviceType.self,
      OccupancySensingTrait.self
    )

    occupancySensorStarter
    time
    condition {
      occupancySensorStarter.occupancy.notEquals(.occupied)
        .and(timeCondition)
    }
     suppress(for: .seconds(43200))  // 12 hours
    parallel {
      action(fan, FanDeviceType.self) {
        update(FanControlTrait.self) {
          $0.setFanMode(.off)
        }
      }
      action(thermostat, ThermostatDeviceType.self) {
        Google.SimplifiedThermostatTrait.setSystemMode(systemMode: .eco)
      }
      action(vacuum, RoboticVacuumCleanerDeviceType.self) {
        RvcRunModeTrait.changeToMode(newMode: 1)
      }
    }
  }
}

如果所有人都外出,而门或窗户传感器被打开,则所有已连接到 Google Home 的智能音箱或显示屏都会广播“入侵警报,入侵警报,入侵警报”

import GoogleHomeSDK
import GoogleHomeTypes

typealias DoorLockTrait = Matter.DoorLockTrait
typealias BooleanStateTrait = Matter.BooleanStateTrait

automation(
  name: "Broadcast intruder alert when door is open if no one is home",
  description:
    """
    If everyone is away and the door or window sensor opens, all Google Home-connected
    smart speaker or displays broadcast 'Intruder Alert, Intruder Alert, Intruder Alert'
    """
) {
  sequential {
    let areaPresenceState = starter(structure, Google.AreaPresenceStateTrait.self)
    areaPresenceState
    condition {
      areaPresenceState.presenceState.equals(.presenceStateVacant)
    }
    let doorLockState = stateReader(
      doorLock,
      DoorLockDeviceType.self,
      DoorLockTrait.self
    )
    // In a Contact Sensor device type, FALSE=open or no contact, TRUE=closed or contact.
    let contactSensorState = stateReader(
      contactSensor,
      ContactSensorDeviceType.self,
      BooleanStateTrait.self
    )
    doorLockState
    contactSensorState
    condition {
      let exp1 = doorLockState.lockState.equals(.unlocked)
      let exp2 = contactSensorState.stateValue.equals(false)
      return exp1.or(exp2)
    }
    action(structure) {
      Google.AssistantBroadcastTrait.broadcast(
        msg: "Intruder Alert, Intruder Alert, Intruder Alert"
      )
    }
  }
}
}

当用户在晚上通过 Chromecast 播放媒体时,系统会启用屏幕镜像功能并放下智能百叶窗(自动化操作)

import GoogleHomeSDK
import GoogleHomeTypes

typealias WindowCoveringTrait = Matter.WindowCoveringTrait

automation(
  name: "Lower blinds when media is played",
  description:
    """
    When users plays media on their Chromecast in the evening, Screen Mirror
    activates and smart blinds lower (Automations)
    """
) {
   select {
    sequential {
      playbackStarter
      time
      let isPlaying = playbackStarter.currentState.equals(.playing)
      condition {
        isPlaying.and(timeCondition)
      }
    }
    starter(structure, Google.VoiceStarterTrait.OkGoogleEvent.self) {
      Google.VoiceStarterTrait.OkGoogleEvent.query("resume my movie night")
    }
  }
  action(nanoleaf4dLight, OnOffLightDeviceType.self) {
    Google.ExtendedModeSelectTrait.changeModeSettings(
      updateModeSettings: [
        Google.ExtendedModeSelectTrait.ModeSetting(
          modeNameKey: "Light Mode",
          modeValueKey: "Screen Mirror"
        )
      ]
    )
  }

  parallel {
    for windowBlind in windowBlinds {
      action(windowBlind, WindowCoveringDeviceType.self) {
        WindowCoveringTrait.downOrClose()
      }
    }
  }
}

当用户暂停 Chromecast 时,屏幕镜像会暂停,智能百叶窗会保持放下状态。用户可以使用“Ok G”或使用遥控器或手机手动恢复 Chromecast。

import GoogleHomeSDK
import GoogleHomeTypes

typealias WindowCoveringTrait = Matter.WindowCoveringTrait

{
  let mediaPlayback = starter(tv, GoogleTVDeviceType.self, MediaPlaybackTrait.self)
  let time = stateReader(structure, Google.TimeTrait.self)
  let timeCondition: TypedExpression<Bool>
  if let localTimeBetweenCondition {
    timeCondition = time.currentTime.between(
      localTimeBetweenCondition.0,
      localTimeBetweenCondition.1
    )
  } else {
    timeCondition = time.currentTime.between(time.sunsetTime, time.sunriseTime)
  }
automation(
  name: "When Chromecast pauses, pause screen mirror",
  description:
    """
    When the user pauses Chromecast, Screen Mirror pauses and smart blinds stay lowered.
    The user can resume Chromecast using "Ok G" or by resuming Chromecast manually using
    a remote or their phone.
    """
) {
  mediaPlayback
  time
  let isPaused = mediaPlayback.currentState.equals(.paused)
  condition {
    isPaused.and(timeCondition)
  }

  action(nanoleaf4dLight, OnOffLightDeviceType.self) {
    Google.ExtendedModeSelectTrait.changeModeSettings(
      updateModeSettings: [
        Google.ExtendedModeSelectTrait.ModeSetting(
          modeNameKey: "Light Mode",
          modeValueKey: "Screen Mirror Pause"
        )
      ]
    )
  }

  parallel {
    for windowBlind in windowBlinds {
      action(windowBlind, WindowCoveringDeviceType.self) {
        WindowCoveringTrait.downOrClose()
        }
      }
    }
  }
}

当用户在 Chromecast 上停止或结束媒体播放时,设备会停止投屏,并恢复到投屏前的原始状态(自动化操作)

import GoogleHomeSDK
import GoogleHomeTypes

typealias WindowCoveringTrait = Matter.WindowCoveringTrait

{
  let playbackState = starter(tv, GoogleTVDeviceType.self, MediaPlaybackTrait.self)
  let time = stateReader(structure, Google.TimeTrait.self)
  let timeCondition: TypedExpression<Bool>
  if let localTimeBetweenCondition {
    timeCondition = time.currentTime.between(
      localTimeBetweenCondition.0,
      localTimeBetweenCondition.1
    )
  } else {
    timeCondition = time.currentTime.between(time.sunsetTime, time.sunriseTime)
  }
automation(
  name: "When media stops, screen mirroring stops",
  description:
    """
    When the user stops/ends media play on the Chromecast, the device stops screen mirroring
    and goes back to the original state that it was on before screen mirror (Automations)
    """
) {
  playbackState
  time
  let isNotPlaying = playbackState.currentState.equals(.notPlaying)

  condition {
    isNotPlaying.and(timeCondition)
  }

  action(nanoleaf4dLight, OnOffLightDeviceType.self) {
    Google.ExtendedModeSelectTrait.changeModeSettings(
      updateModeSettings: [
        Google.ExtendedModeSelectTrait.ModeSetting()
      ]
    )
  }

  parallel {
    for windowBlind in windowBlinds {
      action(windowBlind, WindowCoveringDeviceType.self) {
        WindowCoveringTrait.upOrOpen()
        }
      }
    }
  }
}

如果用户关闭卧室智能电视,且时间在晚上 10 点到凌晨 6 点之间,灯光会变为暖白色,并开始随着时间的推移而缓慢熄灭,而灯条和六边形面板会变暗。

import GoogleHomeSDK
import GoogleHomeTypes

typealias OnOffTrait = Matter.OnOffTrait
typealias LevelControlTrait = Matter.LevelControlTrait
typealias ColorControlTrait = Matter.ColorControlTrait

{
  var matterLights = Set<HomeDevice>()
  var smartHomeLights = Set<HomeDevice>()

  for light in bedroomColorTemperatureLights {
    if let device = await light.types.get(ColorTemperatureLightDeviceType.self) {
      if !device.traits.contains(Google.LightEffectsTrait.self),
        device.traits.contains(Matter.LevelControlTrait.self),
        device.traits[Matter.LevelControlTrait.self]?.supportsMoveWithOnOffCommand ?? false
      {
        matterLights.insert(light)
      } else if device.traits.contains(Google.LightEffectsTrait.self),
        device.traits[Google.LightEffectsTrait.self]?.supportsSleepEffectSetCommand ?? false
      {
        smartHomeLights.insert(light)
      }
    }
  }
automation(
  structureID: structure.id,
  name: "Change lights when Smart TV is off",
  description:
    """
    If user turns bedroom Smart TV off and time is between 10pm - 6am,
    lights change to Warm White and begin to slowly fade off over time,
    light strip and hexagon panels dim.
    """
) {
{
  let tvOnOffState = starter(
    tv,
    GoogleTVDeviceType.self,
    OnOffTrait.self
  )
  let time = stateReader(
    structure,
    Google.TimeTrait.self
  )
  tvOnOffState
  time

  let tvIsOn = tvOnOffState.onOff.equals(false)
  let timeCondition = time.currentTime.between(
    localTimeBetweenCondition.0,
    localTimeBetweenCondition.1
  )

  condition {
    tvIsOn.and(timeCondition)
  }

  parallel {
    for light in matterLights {
      action(light, ColorTemperatureLightDeviceType.self) {
        LevelControlTrait.moveWithOnOff(
          moveMode: .down,
          rate: 1,
          optionsMask: LevelControlTrait.OptionsBitmap.coupleColorTempToLevel,
          optionsOverride: LevelControlTrait.OptionsBitmap.coupleColorTempToLevel
        )
      }
    }

    for light in smartHomeLights {
      action(light, ColorTemperatureLightDeviceType.self) {
        Google.LightEffectsTrait.sleepEffectSet(durationSeconds: 30)
      }
    }

    for lightStrip in bedroomLightStripsAndHexagonPanels {
      action(lightStrip, DimmableLightDeviceType.self) {
        LevelControlTrait.moveWithOnOff(
          moveMode: .down,
          rate: 10,
          optionsMask: LevelControlTrait.OptionsBitmap(),
          optionsOverride: LevelControlTrait.OptionsBitmap()
          )
        }
      }
    }
  }
}