دليل Android DSL للعمليات المبرمَجة المعقّدة

يمكن استخدام لغة DSL الخاصة ببرامج التشغيل الآلي لإنشاء عمليات تشغيل آلي أكثر تعقيدًا من تلك التي تمت مناقشتها في دليل DSL - عمليات التشغيل الآلي الأساسية على Android.

متسلسلة مع إجراءات متعددة

متسلسلة مع إجراءات متعددة

يمكن أن ينفّذ التشغيل الآلي أكثر من إجراء واحد. على سبيل المثال، بدلاً من عقدة action واحدة، يمكنك استخدام عدة عقد action يتم تشغيلها بشكل تسلسلي:

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

متسلسلة مع إجراءات متوازية متعددة

متسلسلة مع إجراءات متوازية متعددة

إذا وضعت عدة عُقد action في عقدة parallel، يتم تنفيذ الإجراءات في الوقت نفسه.

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

إذا كانت هناك عُقد action في العقدة sequential تأتي بعد العقدة parallel، فإنّها تنتظر حتى تنتهي جميع العُقد داخل العقدة parallel من التنفيذ.

التنفيذ الشرطي

تنفّذ عملية التشغيل الآلي العُقد بشكل تسلسلي أو متوازٍ تلقائيًا. إذا كنت بحاجة إلى منطق التفريع الشرطي، أي تنفيذ إجراءات أو مسارات مختلفة استنادًا إلى شروط وقت التشغيل، استخدِم عبارات if-then-else التي يتم إنشاؤها باستخدام كتل DSL للتحكّم في التدفق الشرطي: ifThen وelseIf وorElse.

في حين أنّ عقدة condition العادية تتحكّم في عملية التشغيل الآلي بأكملها (إذا كانت نتيجة تقييم الشرط هي false، يتوقف تنفيذ التشغيل الآلي على الفور)، تتيح وحدات ifThen التحكّم في مسار التشغيل الآلي المتفرّع:

  • عقدة condition: لإيقاف تنفيذ عملية التشغيل الآلي بالكامل (أو مسار التنفيذ الحالي) إذا كان التعبير false.
  • ‫ifThen / elseIf / orElse: لتقييم الشروط بالترتيب إذا كان الشرط false، يتم الانتقال إلى فرع elseIf التالي أو فرع orElse الاحتياطي أو إلى العُقَد اللاحقة في عملية التشغيل الآلي إذا لم يتم استيفاء أي شرط.

تنفيذ إجراء استنادًا إلى شرط معيّن

يقيّم المكوّن ifThen تعبيرًا شرطيًا. إذا تم تقييم التعبير على أنّه true، يتم تنفيذ إجراءات DSL أو العُقد المضمّنة داخل الكتلة. إذا كانت النتيجة false، يتم تخطّي الإجراءات، وتنتقل عملية التشغيل الآلي إلى العُقد اللاحقة في المسار التسلسلي.

يمكنك استخدام مجموعة ifThen مستقلة عندما تريد فقط تنفيذ إجراء بشكل مشروط بدون حظر أو إنهاء العُقَد اللاحقة في التشغيل الآلي:

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

تنفيذ إجراءات مختلفة استنادًا إلى شرط معيّن

لتنفيذ مجموعة واحدة من الإجراءات عندما يكون الشرط صحيحًا ومجموعة بديلة من الإجراءات عندما يكون الشرط خاطئًا، يمكنك ربط كتلة .orElse { ... } الاختيارية بعد ifThen(...) { ... }:

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

ربط شروط متعددة في تسلسل

يمكنك ربط كتلة .elseIf(...) { ... } اختيارية واحدة أو أكثر لتقييم شروط متعددة بالتسلسل. يتم تنفيذ الفرع الأول الذي يتم تقييم شرطه على أنّه true، ويتم تخطّي جميع الفروع المتبقية. إذا لم يتم تقييم أي من الشروط على أنّها true، يتم تنفيذ مجموعة .orElse { ... } اختيارية (إذا تم توفيرها):

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

المسارات المشروطة المُدمَجة

يمكن دمج الوحدات الشرطية داخل وحدات ifThen أو elseIf أو orElse أخرى، بالإضافة إلى دمجها مع عُقد parallel وdelayFor وstateReader.

تنفّذ الكتل ifThen وelseIf وorElse محتواها على شكل تسلسلات متتابعة. يمكنك وضع أي عُقد متسلسلة داخل كل فرع، بما في ذلك action وstateReader وparallel وdelayFor ومجموعات ifThen المتداخلة.

التأخيرات

يمكنك إيقاف عمليات التشغيل الآلي مؤقتًا باستخدام الكلمة الرئيسية delayFor التي تتطلّب وسيطة java.time.Duration تمثّل مدة الإيقاف المؤقت قبل مواصلة التنفيذ. قد تكون مدة الإيقاف المؤقت قصيرة تصل إلى خمس ثوانٍ أو طويلة تصل إلى 24 ساعة.

على سبيل المثال، لتبديل حالة مصباح أربع مرات مع توقّف مؤقت لمدة خمس ثوانٍ بين كل تبديل:

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

تفعيل ميزة "إيقاف"

ميزة "إيقاف التفعيل" هي ميزة تتيح لعملية التشغيل الآلي تجاهل starter لفترة زمنية محدّدة بعد حدث التفعيل الأوّلي. على سبيل المثال، إذا كانت عملية التشغيل الآلي تتضمّن starter يتم تفعيله من خلال كشف الحركة، وإذا حدّدت مدة منع تفعيل تبلغ خمس دقائق، لن يتم تفعيل starter مرة أخرى خلال الدقائق الخمس التالية. يمنع هذا الإجراء تفعيل التشغيل الآلي بشكل سريع ومتكرر.

لتطبيق ميزة "إيقاف المشغّلات" على عملية التشغيل الآلي، استخدِم الكلمة الرئيسية suppressFor مع الوسيطة java.time.Duration التي تمثّل مدة الانتظار قبل الاستجابة للمشغّلات اللاحقة. قد تكون مدة الإيقاف قصيرة لمدة خمس ثوانٍ أو طويلة لمدة 24 ساعة.

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

يُرجى العِلم أنّ إيقاف المشغّلات يؤثر في جميع starters في عملية التشغيل الآلي التي تسبق suppressFor.

الحدّ من عدد عمليات التنفيذ

يمكنك تحديد عدد المرات المسموح فيها بتشغيل عملية التشغيل الآلي.

على سبيل المثال، قد تحتاج إلى إعداد عملية تشغيل آلي لمرة واحدة لتشغيل المكنسة الكهربائية أثناء غيابك عن المنزل طوال اليوم.

ولإجراء ذلك، اضبط حقل البيانات الوصفية maxExecutionCount للتشغيل الآلي. المثال التالي هو عملية تشغيل آلي يمكن تنفيذها مرة واحدة فقط:

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

يتم حذف عملية التشغيل الآلي فورًا بعد اكتمال تنفيذها للمرة الأخيرة والوصول إلى maxExecutionCount. يبقى إدخال سجلّ التشغيل الآلي في علامة التبويب Google Home app (GHA) النشاط، بما في ذلك automation_id.

ضبط سمات السمات في إجراء

لضبط قيمة سمة معيّنة:

  1. أنشئ عقدة update ضمن عقدة action، مع تضمين السمة ذات الصلة كوسيطة لعقدة update:
    action(deviceReference, deviceType) {
      update(trait) {
    
      }
    }
  2. ضمن العقدة update، لكل سمة يتم تعديلها، استخدِم دالة متغيّرة، ومرِّر القيمة الجديدة إليها. لتشكيل اسم دالة التغيير:
    1. استخدِم أحرفًا كبيرة في اسم السمة
    2. أضِف كلمة set كبادئة.
    على سبيل المثال، لتعديل سمة باسم defaultMoveRate، عليك استخدام دالة متغيّرة باسم setDefaultMoveRate.

يُرجى العِلم أنّ عقدة update يمكن أن تتضمّن دوال متعدّدة لتغيير البيانات. في ما يلي مثال على تعديل سمتَين:

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