التحكّم في الأجهزة على نظام التشغيل 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`)، والذي تم تحديده في نموذج بيانات نظام Google Home المتكامل على أنّه toggle(). تغيّر هذه الطريقة قيمة onOff إلى false إذا كانت true، أو إلى true إذا كانت false:

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

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

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

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let _ 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 _ 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 _ 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 \(String(describing: 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)
  }
}