التحكّم في الأجهزة على نظام التشغيل iOS

يتابع هذا الدليل من الوصول إلى الأجهزة والبيانات الوصفية للأجهزة على iOS ويقدّم أمثلة إضافية على التحكّم في الأجهزة والوصول إليها.

لاستخدام أنواع أو سمات أجهزة معيّنة، مثل Matter OnOffTrait المستخدَمة في العديد من الأمثلة الواردة هنا، يجب استيرادها:

import GoogleHomeSDK
import GoogleHomeTypes

التحقّق مما إذا كانت السمة تتيح استخدام أمر

استخدِم الدالة supports على مستوى السمة للتحقّق مما إذا كان أحد الأوامر متوافقًا مع جهاز معيّن.

على سبيل المثال، للتحقّق من توفّر الأمر 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")
}

إرسال أمر إلى جهاز

يشبه إرسال أمر قراءة سمة حالة من سمة. لتشغيل الجهاز أو إيقافه، استخدِم الأمر OnOffTrait Toggle، والذي تم تحديده في toggle() نموذج بيانات منظومة Google Home المتكاملة. تعمل هذه الطريقة على تغيير onOff إلى false إذا كانت true، أو إلى true إذا كانت false:

// Calling a command on a trait.
do {
  try await onOffTraitTest.toggle()
} catch let error as HomeError {
  // Code for handling the exception
}

قد تُعرِض الأوامر استثناءً في حال رصد مشكلة في تدفق التنفيذ. بصفتك مطوّرًا، عليك استخدام عنصر do-catch لمعالجة هذه الاستثناءات بشكلٍ سليم، وعرض معلومات مفصّلة للمستخدمين في الحالات التي يمكن فيها معالجة الأخطاء. سيؤدي عدم معالجة الاستثناءات إلى إيقاف وقت تشغيل التطبيق، وقد يؤدي ذلك بدوره إلى تعطُّل التطبيق.

بدلاً من ذلك، يمكنك استخدام الأمرَين off() أو on() لضبط الحالة صراحةً:

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let error as HomeError {
  // Code for handling the exception
}

بعد إرسال أمر لتغيير الحالة، يمكنك قراءة الحالة بعد اكتمالها كما هو موضّح في قراءة حالة الجهاز للتعامل معها في تطبيقك.

إرسال أمر يتضمّن مَعلمات

قد تستخدِم بعض الطلبات مَعلمات، مثل تلك الواردة في OnOffTrait أو LevelControlTrait:

offWithEffect

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let error as HomeError {
  // Code for handling the exception
}

moveToLevel

// 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 error as HomeError {
  // Code for handling the exception
}

التحقّق مما إذا كانت السمة تتيح استخدام سمة أخرى

قد تتوافق بعض الأجهزة مع سمة Matter، ولكن ليس سمة معيّنة. على سبيل المثال، قد لا يتيح جهاز Cloud-to-cloud الذي تم ربطه بـ Matter كل سمة Matter. لحلّ هذه الحالات، استخدِم السمة isSupported على مستوى السمة للتحقّق مما إذا كانت السمة متوافقة مع جهاز معيّن.

على سبيل المثال، للتحقّق من توافق الجهاز مع سمة "تشغيل/إيقاف" 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!")
}

تكون بعض السمات فارغة في مواصفات Matter أو مخطّط Cloud-to-cloud smart home. بالنسبة إلى هذه السمات، يمكنك تحديد ما إذا كانت القيمة nil التي تعرضها السمة ناتجة عن عدم تسجيل الجهاز لهذه القيمة، أو ما إذا كانت قيمة السمة هي nil فعلاً، وذلك باستخدام isNullable بالإضافة إلى isSupported:

// Check if a nullable attribute is set or is not supported.
if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
  if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] {
    if onOffTrait.attributes.startUpOnOff == nil {
      if onOffTrait.attributes.$startUpOnOff.isSupported {
        print(
          "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning."
        )
      } else {
        print("onOffTrait does not support startUpOnOff!")
      }
    } else {
      print(
        "onOffTrait supports startUpOnOff and it is set to \(onOffTrait.attributes.startUpOnOff)"
      )
    }
  }
}

تعديل سمات السمات

إذا كنت تريد تغيير قيمة سمة معيّنة، ولم تنفِّذ أي من تعليمات السمة ذلك، قد تتيح السمة ضبط قيمتها بشكل صريح.

يعتمد ما إذا كان يمكن تغيير قيمة سمة على عاملَين:

  • هل السمة قابلة للكتابة؟
  • هل يمكن أن تتغيّر قيمة السمة كأثر جانبي لإرسال أحد ملفّات برمجية السمات؟

توفّر المستندات المرجعية للصفات وسماتها هذه المعلومات.

وبالتالي، فإنّ مجموعات السمات التي تحدّد كيفية تغيير قيمة السمة هي:

  • للقراءة فقط ولا تتأثر بالأوامر الأخرى. وهذا يعني أنّ قيمة السمة لا تتغيّر. على سبيل المثال، سمة currentPosition للعنصر SwitchTrait.

  • قابلة للقراءة فقط وتتأثر بأوامر أخرى. وهذا يعني أنّ الطريقة الوحيدة التي يمكن بها تغيير قيمة السمة هي نتيجة إرسال أمر. على سبيل المثال، سمة currentLevel للعنصر LevelControlTrait هي للقراءة فقط، ولكن يمكن تغيير قيمتها باستخدام أوامر مثل moveToLevel.

  • يمكن الكتابة فيها ولا تتأثر بأوامر أخرى. وهذا يعني أنّه يمكنك تغيير قيمة السمة مباشرةً باستخدام الدالة update للسمة، ولكن لا تتوفّر أي أوامر ستؤثّر في قيمة السمة. على سبيل المثال، سمة WrongCodeEntryLimit للعنصر DoorLockTrait.

  • يمكن الكتابة فيها وتتأثر بأوامر أخرى. وهذا يعني أنّه يمكنك تغيير قيمة السمة مباشرةً باستخدام الدالة update للسمة، ويمكن أن تتغيّر قيمة السمة نتيجةً لإرسال أمر. على سبيل المثال، يمكن كتابة قيمة في سمة occupiedCoolingSetpoint للعنصر ThermostatTrait ، ولكن يمكن أيضًا تعديلها باستخدام العبارة setpointRaiseLower.

مثال على استخدام الدالة update لتغيير قيمة سمة

يوضّح هذا المثال كيفية ضبط قيمة سمة DoorLockTrait.wrongCodeEntryLimit بشكل صريح.

لضبط قيمة سمة، استخدِم دالة update السمة مع تمرير دالة تعديل تضبط القيمة الجديدة. من الممارسات الجيدة أولاً التحقّق من أنّ السمة تتيح استخدام سمة.

على سبيل المثال:

if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported {
  let _ = try await doorLockTraitTest.update {
    $0.setWrongCodeEntryLimit(3)
  }
}