Karmaşık otomasyonlar için Android DSL kılavuzu

Otomasyon DSL'si, DSL kılavuzu - Android'de temel otomasyonlar bölümünde ele alınanlardan daha karmaşık otomasyonlar oluşturmak için kullanılabilir.

Birden fazla işlem içeren sıralı

Birden fazla işlem içeren sıralı

Bir otomasyon birden fazla işlem yapabilir. Örneğin, tek bir action düğümü yerine, sıralı olarak çalışan birden fazla action düğümünüz olabilir:

automation {
  sequential {
    starter<_>(...)
    condition {...}
    action {...}
    action {...}
    action {...}
    }
}

Birden fazla paralel işlem içeren sıralı

Birden fazla paralel işlem içeren sıralı

Bir action düğümüne birden fazla parallel düğümü yerleştirirseniz işlemler eşzamanlı olarak yürütülür.

automation {
  sequential {
    starter<_>(...)
    condition {...}
    parallel {
      action {...}
      action {...}
      action {...}
    }
  }
}

sequential düğümünde parallel düğümünden sonra gelen action düğüm varsa parallel düğümündeki tüm düğümlerin yürütülmesi tamamlanana kadar yürütülmeyi beklerler.

Koşullu yürütme

Varsayılan olarak, otomasyonlar düğümleri sırayla veya paralel olarak yürütür. Çalışma zamanı koşullarına göre farklı işlemler veya yollar yürütmek gibi koşullu dallanma mantığına ihtiyacınız varsa koşullu kontrol akışı DSL blokları (ifThen, elseIf ve orElse) kullanılarak oluşturulan if-then-else ifadelerini kullanın.

Standart bir condition düğümü otomasyonun tamamını kontrol ederken (koşul false olarak değerlendirilirse otomasyonun yürütülmesi hemen sonlandırılır) ifThen blokları, dallanma kontrol akışını etkinleştirir:

  • condition node: İfade false ise otomasyonun tamamının (veya mevcut yürütme yolunun) yürütülmesini durdurur.
  • ifThen / elseIf / orElse: Koşulları sırayla değerlendirir. Bir koşul false ise yürütme, sonraki elseIf dalına, orElse yedek dalına düşer veya hiçbir koşul karşılanmazsa otomasyondaki sonraki düğümlerle devam eder.

Bir koşula göre işlem yürütme

ifThen bloğu, koşullu bir ifadeyi değerlendirir. İfade true olarak değerlendirilirse blok içinde iç içe yerleştirilmiş DSL işlemleri veya düğümleri yürütülür. Değer false olursa işlemler atlanır ve otomasyon, sıralı akıştaki sonraki düğümlerle devam eder.

Otomasyondaki sonraki düğümleri engellemeden veya sonlandırmadan yalnızca koşullu olarak bir işlem gerçekleştirmek istediğinizde bağımsız bir ifThen bloğu kullanabilirsiniz:

// When a door opens, turn on the light only if it is off,
// and always broadcast an announcement.
automation {
  sequential {
    val contactState = starter<_>(
      contactSensor,
      ContactSensorDevice,
      BooleanState,
    )
    val lightState = stateReader<_>(
      light,
      DimmableLightDevice,
      OnOff,
    )

    condition {
      // Door opened (contact sensor open)
      expression = contactState.stateValue equals false
    }

    // Conditionally turn on the light if it's off
    ifThen(lightState.onOff equals false) {
      action(light, DimmableLightDevice) { command(OnOff.on()) }
    }

    // Continue executing subsequent actions in the sequential flow
    action(structure) {
      command(AssistantBroadcast.broadcast("The door was opened."))
    }
  }
}

Bir koşula göre farklı işlemler yürütme

Bir koşul doğru olduğunda bir grup işlemi, yanlış olduğunda ise alternatif bir grup işlemi yürütmek için ifThen(...) { ... }'den sonra isteğe bağlı .orElse { ... } bloğunu zincirleyin:

// When the door is unlocked, turn on the entryway light if it is off;
// otherwise, broadcast a welcome message.
automation {
  sequential {
    val doorLockEvent = starter<_>(
      doorLock,
      DoorLockDevice,
      LockOperationEvent,
    )
    val lightState = stateReader<_>(
      light,
      DimmableLightDevice,
      OnOff,
    )

    condition {
      expression =
        doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
    }

    ifThen(lightState.onOff equals false) {
      action(light, DimmableLightDevice) { command(OnOff.on()) }
    }.orElse {
      action(structure) {
        command(AssistantBroadcast.broadcast("Welcome home!"))
      }
    }
  }
}

Birden fazla koşulu sırayla zincirleme

Birden fazla koşulu sırayla değerlendirmek için bir veya daha fazla isteğe bağlı .elseIf(...) { ... } bloğu zincirleyebilirsiniz. Koşulu true olarak değerlendirilen ilk dal yürütülür ve kalan tüm dallar atlanır. Koşullardan hiçbiri true olarak değerlendirilmezse isteğe bağlı bir .orElse { ... } bloğu yürütülür (sağlanırsa):

// Adjust climate controls based on room temperature changes.
automation {
  sequential {
    val tempStarter = starter<_>(
      tempSensor,
      TemperatureSensorDevice,
      TemperatureMeasurement,
    )

    // If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
    ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
      action(thermostat, ThermostatDevice) {
        command(
          SimplifiedThermostat.setSystemMode(
            SimplifiedThermostatSystemModeEnum.Cool
          )
        )
      }
    }.elseIf(tempStarter.measuredValue lessThan 1800) {
      // If temperature is low (< 18°C / 1800 mC), switch to Heat mode
      action(thermostat, ThermostatDevice) {
        command(
          SimplifiedThermostat.setSystemMode(
            SimplifiedThermostatSystemModeEnum.Heat
          )
        )
      }
    }.orElse {
      // Otherwise, turn on the fan
      action(fan, FanDevice) {
        command(OnOff.on())
      }
    }
  }
}

İç içe yerleştirilmiş koşullu akışlar

Koşullu bloklar diğer ifThen, elseIf veya orElse bloklarının içine yerleştirilebilir ve parallel, delayFor ve stateReader düğümleriyle birleştirilebilir.

ifThen, elseIf ve orElse blokları, içeriklerini sıralı akışlar olarak yürütür. action, stateReader, parallel, delayFor ve iç içe yerleştirilmiş ifThen blokları da dahil olmak üzere her bir dalın içine sıralı düğümler yerleştirebilirsiniz.

Gecikmeler

Otomasyonlarınızda delayFor anahtar kelimesini kullanarak duraklatmalar ekleyebilirsiniz. Bu anahtar kelime, yürütmeye devam etmeden önce ne kadar süre duraklatılacağını belirten bir java.time.Duration bağımsız değişkenini alır. Duraklatma süresi beş saniye ile 24 saat arasında olabilir.

Örneğin, bir ışığı her açma/kapama arasında beş saniyelik duraklamayla dört kez açıp kapatmak için:

sequential {
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
  delayFor(Duration.ofSeconds(5))
  action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}

Tetikleyiciyi devre dışı bırakma

Tetikleyici bastırma, otomasyonunuzun ilk tetikleyici etkinlikten sonra belirli bir süre boyunca starter değerini yoksaymasına olanak tanıyan bir özelliktir. Örneğin, otomasyonda hareket algılama ile tetiklenen bir starter varsa ve tetikleyiciyi bastırma süresini beş dakika olarak belirtirseniz starter tetiklendiğinde sonraki beş dakika boyunca tekrar tetiklenmez. Bu, otomasyonun tekrar tekrar hızlı bir şekilde tetiklenmesini önler.

Otomasyonunuza tetikleyici bastırma uygulamak için suppressFor anahtar kelimesini kullanın. Bu anahtar kelime, sonraki tetikleyicilere yanıt vermeden önce ne kadar süre bekleneceğini gösteren bir java.time.Duration bağımsız değişkeni içerir. Bastırma süresi en az beş saniye veya en fazla 24 saat olabilir.

automation {
  sequential {
    val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
    suppressFor(Duration.ofMinutes(30))
    action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}

Tetikleyici bastırmanın, otomasyonda suppressFor'dan önce gelen tüm starters'ları etkilediğini unutmayın.

Yürütme sayısını sınırlama

Otomasyonun çalıştırılabileceği sayıyı sınırlayabilirsiniz.

Örneğin, gün içinde evden uzaktayken elektrikli süpürgeyi çalıştıran tek seferlik bir otomasyon ayarlamak isteyebilirsiniz.

Bunu yapmak için otomasyonun maxExecutionCount meta veri alanını ayarlayın. Aşağıdaki örnek, yalnızca bir kez çalıştırılabilen bir otomasyondur:

automation {
  // The automation can only be executed once.
  maxExecutionCount = 1
  // When the door lock state changes
  sequential {
    val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent)
    // if the door is unlocked
    condition() {
      expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock)
    }
    // turn the light on
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

Otomasyon, son kez yürütme işlemi tamamlandığında ve maxExecutionCount sınırına ulaşıldığında hemen silinir. Otomasyonun geçmiş girişi, Google Home app (GHA) Etkinlik sekmesinde kalır (automation_id dahil).

Bir işlemde özellik özelliklerini ayarlama

Bir özellik özelliğinin değerini ayarlamak için:

  1. action düğümü içinde update düğümü oluşturun. İlgili özelliği update düğümüne bağımsız değişken olarak ekleyin:
    action(deviceReference, deviceType) {
      update(trait) {
    
      }
    }
  2. update düğümünde, değiştirilecek her özellik için bir mutasyon işlevi kullanın ve yeni değeri bu işlevle iletin. Değiştirici işlevinin adını oluşturmak için:
    1. Özelliğin adını büyük harfle yazın.
    2. set kelimesini ekleyin.
    Örneğin, defaultMoveRate adlı bir özelliği güncellemek için setDefaultMoveRate adlı bir değiştirici işlev kullanırsınız.

Bir update düğümünün birden fazla değiştirici işlevi olabileceğini unutmayın. İki özelliğin güncellendiği bir örneği aşağıda görebilirsiniz:

action(device, Fan) {
  update(FanControl) {
    setPercentSetting(50u)
    setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
  }
}