دليل لغات وصف البيانات (DSL) لنظام التشغيل iOS

استخدِم الدليل التالي لفهم كيفية استخدام العقد المختلفة في Automation DSL لإنشاء عملية آلية.

يتم وضع جميع لغة DSL للتشغيل الآلي ضمن عقدة automation واحدة. تشكل عقدة automation الحدود بين سياق لغة Swift الخارجي وسياق DSL المضمّن.

التدفق التسلسلي

إنّ المسار التسلسلي هو النوع التلقائي لمسار التشغيل الآلي.

مثال على لغة وصف برمجي متسلسلة

في ما يلي نموذج أساسي جدًا لـ Automation DSL يستخدم تسلسلاً متّصلاً يتألّف من عنصر بدء وحالة وإجراء:

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {
  starter(...)
  condition {...}
  action {...}
}

ويمكن تحسين ذلك من خلال إضافة عقد إضافية.

مبتدئ

تحدِّد العقد المشغِّلة الظروف الأولية التي تفعِّل عملية التشغيل الآلي. على سبيل المثال، عند حدوث تغيير في الحالة أو القيمة. يجب أن تحتوي العملية المبرمَجة على عامل إشعال واحد على الأقل، وإلا لن تجتاز عملية التحقّق. لإضافة أكثر من خطوة بدء واحدة إلى عملية تشغيل آلي، عليك استخدام عقدة select.

النموذج الأساسي المستنِد إلى سمة السمة

عند الإعلان عن عقدة بداية تستند إلى سمة سمة، حدِّد ما يلي:

  • الجهاز
  • نوع الجهاز الذي تنتمي إليه السمة
  • السمة
starter(
  thermostat,
  Matter.TemperatureSensorDeviceType.self,
  Matter.TemperatureMeasurementTrait.self
)

تكون مَعلمة نوع الجهاز مطلوبة لأنّها تتيح لك تحديد نوع الجهاز الذي يتعامل معه الإجراء المبرمَج ضمن الجهاز. على سبيل المثال، قد يكون الجهاز مكوّنًا من FanDeviceType و HeatingCoolingUnitDeviceType، وكلاهما يحتوي على سمة OnOffTrait. من خلال تحديد نوع الجهاز، لا يكون هناك أي غموض حول الجزء الذي يؤدي إلى بدء التشغيل الآلي في الجهاز.

بدء الحملة استنادًا إلى الحدث

عند الإعلان عن عقدة بداية تستند إلى حدث، حدِّد ما يلي:

  • الجهاز
  • نوع الجهاز الذي تنتمي إليه السمة
  • الحدث
starter(
  doorbell,
  Google.GoogleDoorbellDeviceType.self,
  Google.DoorbellPressTrait.DoorbellPressedEvent
)

نموذج أساسي يستند إلى بنية وحدث، مع مَعلمات

يمكن أن تحتوي بعض الأحداث على مَعلمات، لذا يجب أيضًا تضمين هذه المَعلمات في المشغِّل.

على سبيل المثال، يستخدم هذا الإجراء المشغِّل ScheduledEvent في TimeTrait لتفعيل الإجراء المبرمَج في الساعة 7:00 صباحًا:

typealias TimeTrait = Google.TimeTrait

let earlyMorning = starter(
  structure,
  TimeTrait.ScheduledEvent.self
) {
  TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}

نظام التشغيل اليدوي

إنّ أداة البدء اليدوية هي نوع خاص من أدوات البدء التي تسمح للمستخدم ب تشغيل التشغيل الآلي يدويًا.

عند تحديد مشغّل يدوي:

  • لا تحدِّد سمة أو نوع جهاز.
  • قدِّم عنصر واجهة مستخدم يستدعي Automation.execute().

عند وضع إجراء تفعيل يدوي في مسار select مع إجراء تفعيل آخر، يتم إلغاء الإجراء الآخر من خلال الإجراء اليدوي:

select {
  manualStarter()
  starter(
    thermostat,
    Matter.TemperatureSensorDeviceType.self,
    Matter.TemperatureMeasurementTrait.self
  )
}

يُرجى العِلم أنّه سيتم تقييم أيّ عقد condition بعد بدء يدوي، وقد يؤدي ذلك إلى حظر تنفيذ التشغيل الآلي، وذلك استنادًا إلى تعبير condition.

فصل أداة البدء اليدوية عن أداة البدء الشَرطية

من بين طرق تنظيم التشغيل الآلي لكي لا تحظر عقد condition عملية تشغيل آلي تم تفعيلها باستخدام مشغّل يدوي، هي وضع مشغّل الإجراء الآخر في تسلسل منفصل مع condition:

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {

  select {
    sequential {
      starter(...)
      condition {...}
    }
    sequential {
      manualStarter()
    }
  }
  action {...}

}

الإشارة إلى قيمة سمة

لاستخدام قيمة سمة في تعبير، استخدِم البنية التالية.

باستخدام stateReader:

typealias TimeTrait = Google.TimeTrait

let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime

باستخدام starter:

typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait

let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
  starterNode.onOff.equals(true)
}

عقد الشروط والتعبيرات

تمثّل عقدة الشرط نقطة قرار تحدّد ما إذا كان سيتم مواصلة الإجراء المبرمَج أم لا. يمكن أن تتضمّن عملية التشغيل الآلي عدّة عقد condition. إذا كانت قيمة تعبير أيّ من عقد condition هي false، ينتهي تنفيذ الإجراء التلقائي بالكامل.

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

يتم إنشاء التعبيرات بشكل مشابه للتعبيرات في Swift، وقد تحتوي على قيم أساسية مثل الأرقام والأحرف والسلاسل والقيم المنطقية، بالإضافة إلى قيم Enum. يتيح لك تجميع التعبيرات الفرعية بين قوسين التحكّم في الترتيب الذي يتم تقييمها به.

في ما يلي مثال على condition يجمع بين تعبيرات فرعية متعددة في تعبير واحد:

condition {
  let exp1 = starterNode.lockState.equals(.unlocked)
  let exp2 = stateReaderNode.lockState.equals(true)
  let exp3 = occupancySensingDevice.occupied.notEquals(0)
  (exp1.and(exp2)).or(exp3)
}

يمكنك الإشارة إلى قيمة سمة يتم الوصول إليها من خلال عنصر بدء:

typealias OnOffTrait = Matter.OnOffTrait

let starterNode = starter(device, OnOffTrait.self)
starterNode
condition {
  starterNode.onOff.equals(true)
}
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }

stateReader

الطريقة الأخرى للإشارة إلى قيم سمات السمات في عقدة condition هي باستخدام عقدة stateReader.

لإجراء ذلك، عليك أولاً تسجيل قيمة سمة السمة في عقدة stateReader. تأخذ الدالة stateReader العنصر structure والسمة كوسيطات:

typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait

let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)

بعد ذلك، يمكنك الإشارة إلى stateReader في عقدة condition:

condition {
filterMonitoringState.changeIndication.equals(.warning)
}

باستخدام عوامل المقارنة و عوامل التشغيل المنطقية، يمكن استخدام stateReaders متعددة في عقدة condition:

typealias ArmDisarm = Google.ArmDisarmTrait
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLock = Matter.DoorLockTrait

let armState = stateReader(doorLock, DoorLockDevice.self, ArmDisarm )
let doorLockState = stateReader(doorLock, DoorLockDevice.self, DoorLock)
armState
doorLockState
condition {
  let exp1 = armState.armState
  let exp2 = doorLockState.lockState
  exp1.and(exp2)
}

مدة الشرط

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

condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}

يمكن أن تتراوح المدة بين دقيقة واحدة و30 دقيقة.

عقد الإجراءات

عقدة الإجراء هي المكان الذي يتم فيه تنفيذ التشغيل الآلي. في هذا المثال، يُستخدَم الإجراء لتشغيل الأمر broadcast() في AssistantBroadcastTrait:

action(speaker, SpeakerDeviceType.self) {
  Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}