إنشاء تطبيق جوّال باستخدام واجهات برمجة التطبيقات Home APIs على أجهزة iOS

1. مقدمة

f154e30306882c74.png

ما هي واجهات برمجة تطبيقات Home؟

توفّر واجهات برمجة تطبيقات Google Home مجموعة من المكتبات للمطوّرين للاستفادة من منظومة Google Home المتكاملة. باستخدام واجهات برمجة التطبيقات Home APIs، يمكن للمطوّرين إنشاء تطبيقات تتيح تفعيل الأجهزة المنزلية الذكية والتحكّم فيها بسلاسة.

3e11583c779a2cec.png

مكونات Home APIs

تتألف واجهات برمجة تطبيقات Home من:

  • واجهات برمجة التطبيقات Device وStructure: للتفاعل مع منزل المستخدم يمكن للتطبيقات استخدام واجهات برمجة التطبيقات هذه لقراءة معلومات عن الأجهزة والغرف والهياكل (على سبيل المثال، الاطّلاع على درجة حرارة الترموستات الحالية) والتحكّم في الأجهزة (على سبيل المثال، تغيير درجة الحرارة المثلى المضبوطة في الترموستات).
  • واجهة برمجة التطبيقات لإعداد الأجهزة: يمكنك إعداد أجهزة Matter الجديدة في النسيج بأقل جهد ممكن.
  • Automation API: يمكنك إنشاء عمليات التشغيل الآلي وحذفها وإجراء طلبات بحث عنها ضمن منزل المستخدم.

المتطلبات الأساسية

المُعطيات

  • كيفية إنشاء تطبيق iOS باستخدام واجهات برمجة تطبيقات Home مع أفضل الممارسات
  • كيفية استخدام Device وStructure API لتمثيل المنزل الذكي والتحكّم فيه
  • كيفية استخدام واجهة برمجة التطبيقات Commissioning API لإضافة أجهزة إلى منظومة Google Home المتكاملة
  • كيفية استخدام Automation API لإنشاء عملية تشغيل آلي أساسية

2. إعداد منزلك

تجهيز الأجهزة

يوفّر Google Home Playground مجموعة متنوعة من أجهزة المنزل الذكي المحاكية المُعدّة مسبقًا، ويُنصح باستخدامه لاستكشاف الإمكانات الكاملة لواجهات برمجة تطبيقات Home، خاصةً إذا كان لديك عدد محدود من الأجهزة في منزلك.

اتّبِع التعليمات لتسجيل الدخول إلى Google Home Playground وإكمال ربط الحساب في تطبيق Google Home. بعد إكمال ذلك، من المفترض أن تتمكّن من رؤية الأجهزة في علامة التبويب "الأجهزة" في تطبيق Google Home.

c892afce113abe8f.png

3- الإعداد

الحصول على رمز التطبيق النموذجي

ابدأ باستنساخ رمز المصدر من GitHub:

git clone https://github.com/google-home/google-home-api-sample-app-ios.git

يحتوي دليل العيّنات على فرعَين، start وfinished، لهذا الدليل التعليمي.

  • start: الرمز البرمجي الأوّلي لهذا المشروع الذي ستُجري عليه تغييرات لإكمال الدرس التطبيقي.
  • finished: الرمز البرمجي المكتمل لهذا الدرس التطبيقي، والذي يُستخدَم للتحقّق من عملك

استكشاف رمز "البدء"

ابدأ هذا الدليل التعليمي عن طريق التبديل إلى فرع start من المستودع المُنشئ من النسخة:

git checkout start

يحتوي هذا الفرع على الرمز البرمجي الأوّلي للمشروع. ستُعدّل هذه التعليمات البرمجية خلال ورشة إعداد الرموز البرمجية لتنفيذ الوظائف الكاملة. يقدّم نموذج التطبيق في الدرس التطبيقي حول الترميز بنية أساسية تم إنشاؤها باستخدام Swift للتفاعل مع حزمة تطوير البرامج (SDK) لـ Home APIs في نظام التشغيل iOS. لنلقِ نظرة سريعة على المكونات الرئيسية في مشروع start:

  • Main Entry (GoogleHomeAPISampleIOSApp): هذه هي نقطة دخول التطبيق الرئيسية، وهي متوفّرة في GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift. وهي تضبط حزمة تطوير البرامج (SDK) وتبدئها وتُعدّ واجهة المستخدم الأساسية.
  • Core Views (View/):
    • MainView.swift: طريقة العرض الجذر بعد الإطلاق، التي تحتوي على NavigationView الرئيسي وتتولى هذه العملية اختيار بنية Google Home النشطة وعرض StructureView المقابل.
    • StructureView.swift: تعرِض هذه الصفحة محتوى البنية المحدّدة حاليًا، باستخدام علامات التبويب للتبديل بين شبكة الأجهزة وقائمة عمليات التشغيل الآلي. ويقدّم أيضًا قوائم لإضافة غرف أو أجهزة.
    • DeviceView.swift: يمثّل المربّع التفاعلي لجهاز واحد ضمن شبكة StructureView.
    • AutomationsView.swift: تعرِض هذه الصفحة قائمة الإجراءات المبرمَجة الحالية للبنية، كما تتيح التنقّل لإنشاء تفاصيل الإجراءات المبرمَجة أو عرضها.
  • ViewModels (ViewModel/): تدير هذه الفئات حالة العرض ومنطقه.
    • AccountViewModel.swift: تعالج عملية الاتصال بكائن Home وتدير حالة المصادقة.
    • MainViewModel.swift: تُدير قائمة عناصر Structure المتاحة وتتتبّع البنية المحدّدة.
    • StructureViewModel.swift: تُدير عرض الغرف وعناصر DeviceControl داخل البنية المحدّدة.
    • AutomationList.swift وAutomationViewModel.swift وما إلى ذلك: تُستخدَم هذه الوظائف للحصول على الإجراءات المبرمَجة وعرضها وإنشائها وإدارتها.
  • Device Controls (ViewModel/Device/):
    • DeviceControl.swift: فئة أساسية لتمثيل الأجهزة التي يمكن التحكّم فيها في واجهة المستخدم
    • الفئات الفرعية المحدّدة (LightControl.swift وFanControl.swift وOnOffPlugInUnitControl.swift وما إلى ذلك): تنفيذ منطق واجهة المستخدم والتحكّم في الجهاز وربط الحالات لأنواع الأجهزة المختلفة استنادًا إلى سماتها
    • DeviceControlFactory.swift: مسؤول عن إنشاء فئة فرعية DeviceControl المناسبة لفئة HomeDevice معيّنة.
  • Commissioning (Commissioning/):
    • CommissioningManager.swift: يحتوي على منطق إدارة عملية تفعيل جهاز Matter.
  • Utilities & UX (Utils/, UX/, Storage/): يحتوي على رمز مساعد لعناصر واجهة المستخدم (الألوان والسمات) ومعالجة الأخطاء وتخزين البيانات (SelectedStructureStorage.swift) وأدوات أخرى.

خلال هذا الدليل التعليمي حول الرموز البرمجية، ستعثر على تعليقات مثل TODO أو وحدات رموز برمجية تم التعليق عليها وتنبيهات ضمن مشروع start. تُحدِّد هذه العلامات الأقسام التي ستضيف فيها رمزًا أو تزيل تعليقه لتنفيذ الوظيفة المطلوبة، وذلك باتّباع الخطوات المقدَّمة.

إنشاء ملفات إعداد نشر Apple

لضبط App Attest، اتّبِع التعليمات الواردة في مقالة ملفّات ضبط عمليات النشر في Apple. يُرجى العِلم أنّه بعد الإعداد، لا يمكن نشر التطبيق إلا على جهاز حقيقي، وليس في محاكي.

إعداد المصادقة

للحصول على معرّف عميل OAuth وتفعيل Home APIs، عليك أولاً تسجيل الدخول إلى Google Cloud وإنشاء مشروع جديد أو اختيار مشروع حالي. بعد ذلك، اتّبِع الخطوات المقدَّمة لإنشاء معرِّف عميل OAuth وتفعيل Home APIs وإضافة حسابك إلى قائمة المسموح بها.

إعداد حزمة تطوير البرامج (SDK)

احصل على حزمة تطوير البرامج (SDK) لـ Home APIs على نظام التشغيل iOS وضبطها من خلال الرجوع إلى تعليمات الإعداد الواردة في مقالة إعداد حزمة SDK. احرص على استبدال HOME_API_TODO_ADD_APP_GROUP بمجموعة التطبيقات الخاصة بك.

إنشاء المشروع وتشغيله

بعد إنشاء المشروع وتشغيله باستخدام الفرع start، من المفترض أن يظهر مربّع حوار TODO وشاشة تعرض "يجب تسجيل الدخول". سيتم تنفيذ تفاعل Home APIs في الأقسام التالية.

bd56b7080037e38a.png 9c0f08a3f4197a77.png

ملاحظة: حدِّد مكان الرمز الذي يجب تعديله من خلال البحث في المشروع عن النص المعروض في مربّع الحوار. على سبيل المثال، ابحث عن "TODO: initialize Home".

4. الإعداد

إعداد المنزل

قبل استخدام أيّ من واجهات برمجة التطبيقات Home APIs لنظام التشغيل iOS، عليك إعداد Home في تطبيقك. وHome هو الإدخال من المستوى الأعلى لحزمة SDK، ويوفّر إمكانية الوصول إلى جميع الكيانات في بنية المستخدم. عند طلب جميع الكيانات من نوع معيّن، تعرض واجهة برمجة التطبيقات عنصر Query يتيح لك اختيار كيفية تلقّي النتائج. في GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift، أزِل التعليق والتنبيه في connect() لتنفيذ عملية إعداد المنزل.

  /// TODO: initialize Home
  /// Remove comments to initialize Home and handling permission.
  private func connect() {
    Task {
      do {
        self.home = try await Home.connect()
      } catch {
        Logger().error("Auth error: \(error).")
      }
    }
  }

إذن استخدام واجهات برمجة التطبيقات Home APIs

ستظهر شاشة الموافقة عند تشغيل التطبيق. اختَر بنية Google Home واختَر الحساب المدرَج في القائمة المسموح بها لمشروعك على Google Cloud.

47310f458c0094d9.png 4a571dbd9979a88c.png e29c75891a3a67af.png

5- الأجهزة والهياكل

الحصول على الغرف والأجهزة

في GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift، أزِل التعليق والتنبيه في getRoomsAndDevices() للحصول على الغرف والأجهزة في البنية المحدّدة باستخدام home.rooms() وhome.devices() على التوالي.

  /// TODO: get rooms and devices
  /// Remove comments to get the rooms and devices from home entry
  private func getRoomsAndDevices(){
    self.home.rooms().batched()
      .combineLatest(self.home.devices().batched())
      .receive(on: DispatchQueue.main)
      .catch { error in
        Logger().error("Failed to load rooms and devices: \(error)")
        return Just((Set<Room>(), Set<HomeDevice>()))
      }
      .map { [weak self] rooms, devices in
        guard let self = self else { return [] }
        self.hasLoaded = true
        return self.process(rooms: rooms, devices: devices)
      }
      /// receive from .map and .assign() to publisher entries
      .assign(to: &self.$entries)
  }

تضمن وظيفة process() أولاً أنّ الأجهزة في الغرفة نفسها قبل أن تجعلها تتفاعل كمجموعة HomeDevices باستخدام DeviceControl وDeviceControlFactory.

4c677c4c294e67ca.png

ملاحظة: إذا لم يكن جهازك مُدرَجًا في DeviceControlFactory، ستظهر القيمة "غير متوافق". للاطّلاع على مزيد من المعلومات حول الأجهزة المتوافقة، يُرجى الاطّلاع على صفحة أنواع الأجهزة المتوافقة على نظام التشغيل iOS.

التفاعل مع جهاز

يكون مفتاح التوصيل outlet1 غير مفعَّل في البداية عند النقر عليه أو التمرير عليه على الأجهزة. لتفعيل التفاعل معه، حدِّد موقع GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift وأزِل التعليق والتنبيه ضمن الدالة primaryAction().

  /// TODO: primary action of OnOffPlug
  /// Toggles the plug; usually provided as the `action` callback on a Button.
  public override func primaryAction() {
    self.updateTileInfo(isBusy: true)
    Task { @MainActor [weak self] in
      guard
        let self = self,
        let onOffPluginUnitDeviceType = self.onOffPluginUnitDeviceType,
        let onOffTrait = onOffPluginUnitDeviceType.matterTraits.onOffTrait
      else { return }

      do {
        try await onOffTrait.toggle()
      } catch {
        Logger().error("Failed to to toggle OnOffPluginUnit on/off trait: \(error)")
        self.updateTileInfo(isBusy: false)
      }
    }
  }

تعمل الدالة primaryAction()، المتوفّرة ضمن فئة OnOffPlugInUnitControl، على تبديل حالة التشغيل/الإيقاف لموصّل ذكي أو أي جهاز يمثّله OnOffPluginUnitDeviceType.

تتوفّر أمثلة إضافية على عناصر التحكّم بالأجهزة في GoogleHomeAPISampleIOS/ViewModel/Device.

إنشاء غرفة جديدة

تتيح Structure API إنشاء الغرف وحذفها، بالإضافة إلى نقل الأجهزة بين الغرف.

في GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift، أزِل التعليق والتنبيه في addRoom().

  /// TODO: add room
  /// Add a new room in a given structure.
  func addRoom(name: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.createRoom(name: name)
      } catch {
        Logger().error("Failed to create room: \(error)")
      }
    }
  }

لإنشاء غرفة جديدة باستخدام structure.createRoom()، انتقِل إلى أعلى يمين الشاشة وانقر على رمز"+" > إضافة غرفة. أدخِل اسم الغرفة الجديد وانقر على "إنشاء غرفة". ستظهر الغرفة الجديدة بعد بضع ثوانٍ.

b122ae6642b7da1c.png a45f785e1d51938e.png 7753b56cbdcff8d6.png

نقل الجهاز إلى غرفة مختلفة

في GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift، أزِل التعليق والتنبيه في moveDevice().

  /// TODO: move device
  /// Move a device into a different room.
  func moveDevice(device deviceID: String, to roomID: String, structure: Structure) {
    Task {
      do {
        _ = try await structure.move(device: deviceID, to: roomID)
      } catch {
        Logger().error("Failed to move to room: \(error)")
      }
    }
  }

لنقل الجهاز باستخدام الرمز structure.move()، اضغط عليه مع الاستمرار، ثم اختَر "نقل الجهاز إلى غرفة أخرى"، ثم اختَر الغرفة الجديدة.

f9627592af44163d.png fd126fabb454f2bf.png 813e1e23e50cd9f6.png

حذف غرفة فارغة

في GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift، أزِل التعليق والتنبيه في removeRoom().

  /// TODO: delete room
  /// Delete an empty room in a given structure.
  func removeRoom(id: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.deleteRoom(id: id)
      } catch {
        Logger().error("Failed to remove room: \(error)")
      }
    }
  }

لحذف غرفة فارغة باستخدام structure.deleteRoom()، انقر على رمز المهملات على يسار اسم الغرفة وأكِّد الإجراء. يُرجى العِلم أنّه لا يمكن حذف سوى الغرف الفارغة.

4f129262ad67f564.png

ملاحظة: انقل الجهاز مرة أخرى لإنشاء غرفة فارغة.

6. الإعداد

ملاحظة: يتطلب هذا القسم استخدام مركز Google وجهاز Matter. تأكَّد من أنّ مركز Google في البنية متصل بالإنترنت ويمكن الوصول إليه. إذا لم يكن لديك جهاز Matter، جرِّب استخدام تطبيق Matter Virtual Device بدلاً من ذلك.

إضافة جهاز Matter

تتيح واجهة برمجة التطبيقات Commissioning API لتطبيقك إضافة أجهزة Matter جديدة إلى منزل المستخدم وحسابه على Google. ويوفر ذلك تجربة إعداد سلسة مباشرةً داخل تطبيقك.

في GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift، أزِل التعليق والتنبيه في addMatterDevice().

  /// TODO: add Matter Device
  /// Starts the Matter device commissioning flow to add the device to the user's home.
  /// - Parameters:
  ///   - structure: The structure to add the device to.
  ///   - add3PFabricFirst: Whether to add the device to a third party fabric first.
  public func addMatterDevice(to structure: Structure, add3PFabricFirst: Bool) {
    self.isCommissioning = true

    /// pass if it's 1p or 3p commissioning
    let userDefaults = UserDefaults(
      suiteName: CommissioningManager.appGroup)
    userDefaults?.set(
    add3PFabricFirst, forKey: CommissioningUserDefaultsKeys.shouldPerform3PFabricCommissioning)

    Task {
      do {
        try await structure.prepareForMatterCommissioning()
      } catch {
        Logger().error("Failed to prepare for Matter Commissioning: \(error).")
        self.isCommissioning = false
        return
      }

      // Prepare the Matter request by providing the ecosystem name and home to be added to.
      let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "Google Home",
        homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
      )
      let request = MatterAddDeviceRequest(topology: topology)

      do {
        Logger().info("Starting MatterAddDeviceRequest.")
        try await request.perform()
        Logger().info("Completed MatterAddDeviceRequest.")
        let commissionedDeviceIDs = try structure.completeMatterCommissioning()
        Logger().info("Commissioned device IDs: \(commissionedDeviceIDs).")
      } catch let error {
        structure.cancelMatterCommissioning()
        Logger().error("Failed to complete MatterAddDeviceRequest: \(error).")
      }

      self.isCommissioning = false
    }
  }

لإنشاء غرفة جديدة باستخدام structure.prepareForMatterCommissioning()، انتقِل إلى أعلى يمين الشاشة وانقر على رمز"+" > إضافة جهاز إلى Google Fabric. ويستخدم MatterAddDeviceRequest لإضافة جهاز Matter إلى غرفتك. بعد اختيار الغرفة واسم الجهاز، يتم عرض الجهاز في شاشة "الأجهزة".

adf6cbb531787aaf.png f002bd6320bc480d.png

7. التشغيل الآلي

عرض جميع عمليات التشغيل الآلي في البنية

انقر على الإجراءات المبرمَجة في شريط التنقّل أسفل الشاشة. ستُدرج جميع عمليات التشغيل الآلي في بنيتك باستخدام structure.listAutomations().

cc6d50f72f812c24.png

ملاحظة: إذا لم تكن قد أعددت أي عمليات تشغيل آلي للمنزل، ستظهر لك الرسالة "إضافة عملية تشغيل آلي للبدء".

إنشاء عملية تشغيل آلي

بعد أن تعرّفت على Device وStructure API وإضافة جهاز جديد، حان وقت إنشاء عملية تشغيل آلي جديدة باستخدام Automation API.

في GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift، أزِل التعليق والتنبيه وقاعدة التشغيل الآلي الفارغة في lightAutomation().

  /// TODO: create automation
  /// - Parameter devices: devices in current selected structure
  /// - Returns: the automation object to be created
  /// This automation will turn off the light after 5 seconds.
  public func lightAutomation(devices: Set<HomeDevice>) async throws -> any DraftAutomation {
    let light = devices.first { $0.name == "light2" }
    
    guard let light else {
      Logger().error("Unable to find light device with name light2")
      throw HomeError.notFound("No devices support OnOffLightDeviceType")
    }
    
    return automation(
      name: "Turn off light after 5 seconds",
      description:
        """
        Turns off light2 after it has been on for 5 seconds.
        """
    ) {
      let onOffStarter = starter(light, OnOffLightDeviceType.self, OnOffTrait.self)
      onOffStarter
      condition {
        onOffStarter.onOff.equals(true)
      }
      delay(for: Duration.seconds(5))
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
  }

لإنشاء عملية مبرمَجة تعمل على إطفاء المصباح بعد خمس ثوانٍ من تشغيله، انتقِل إلى عرض "الإجراءات المبرمَجة" وانقر على الزر + إضافة. بعد ذلك، اختَر إطفاء الإضاءة بعد 5 ثوانٍ. ستظهر تفاصيل التشغيل الآلي، بما في ذلك starter وcondition وaction. انقر على حفظ لإنشاء عملية التشغيل الآلي من خلال structure.createAutomation().

21c1f8ea2a29134b.png 4bd36f6ed9c5f6e9.png

ملاحظة: تعتمد الإجراءات المبرمَجة المتاحة على الأجهزة في منزلك. إذا لم تظهر لك أي إجراءات مبرمَجة متاحة، جرِّب إعادة تسمية جهاز الإضاءة إلى "مصباح2".

ارجع إلى علامة التبويب "الأجهزة" وفعِّل مصباح الإضاءة المُسمى "light2". سيتم إيقافه تلقائيًا بعد خمس ثوانٍ.

تشمل مكونات عملية التشغيل الآلي ما يلي:

  • الحدث المُشغِّل: هو حدث يبدأ التشغيل الآلي. في هذا المثال، ستبدأ عملية التشغيل الآلي بعد حدوث تغيير في OnOffTrait.
  • الحالة: للتحقّق مما إذا كان جهاز التفعيل يستوفي متطلبات معيّنة. في هذه الحالة، سيتم تنفيذ العملية المبرمَجة إذا كان المصباح مضاءً.
  • الإجراء: هذا هو الإجراء الآلي الذي تريد تنفيذه، ولكن فقط إذا كان المشغِّل يستوفي المتطلبات. في حال استيفاء الشروط، سيتم إطفاء المصباح.

للاطّلاع على أمثلة إضافية، يُرجى الانتقال إلى صفحة أمثلة على الإجراءات المبرمَجة.

حذف عملية تشغيل آلي

يتمّ استدعاء الطريقة structure.deleteAutomation() عند التمرير سريعًا لليسار على عملية التشغيل الآلي الحالية والنقر على رمز المهملات لإزالتها من البنية.

dc678cd9e16f89a5.png

8. تهانينا

تهانينا! لقد أنشأت تطبيقًا أساسيًا للمنزل الذكي باستخدام واجهات برمجة تطبيقات Home APIs لنظام التشغيل iOS.

الإنجازات التي حقّقتها:

  • الإعداد: ربط تطبيقك بمنظومة Google Home المتكاملة باستخدام Home.connect()
  • الأذونات: تعالج مصادقة المستخدم وتفويضه للوصول إلى بيانات المنزل.
  • الأجهزة والهياكل: يتم جلب الغرف والأجهزة وعرضها باستخدام home.rooms() وhome.devices().
  • التحكّم في الجهاز: تفاعل الجهاز الذي تم تنفيذه، مثل تبديل حالة OnOffPluginUnitDeviceType من خلال استدعاء الأوامر المتعلّقة بسماته
  • إدارة البنية: تمت إضافة وظائف لإنشاء غرف جديدة (structure.createRoom()) ونقل الأجهزة بين الغرف (structure.move()) وحذف الغرف الفارغة (structure.deleteRoom()).
  • الإعداد: تم دمج عملية إعداد حزمة SDK لإضافة أجهزة Matter الجديدة (MatterAddDeviceRequest).
  • التشغيل الآلي: استكشاف كيفية إدراج عمليات التشغيل الآلي وإنشائها (structure.createAutomation()) وحذفها (structure.deleteAutomation()) ضمن بنية

لقد حصلت الآن على فهم أساسي لكيفية الاستفادة من واجهات برمجة التطبيقات Home APIs لإنشاء تجارب غنية للتحكّم في المنزل الذكي على أجهزة iOS.

الخطوات التالية:

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

أحسنت!