Android এর জন্য ডিভাইস এবং ডিভাইস মেটাডেটা অ্যাক্সেস করুন

অ্যান্ড্রয়েডের হোম এপিআই-এর মাধ্যমে ডিভাইস এপিআই অ্যাক্সেস করা যেতে পারে। এই প্যাকেজগুলি আপনার অ্যাপে ইম্পোর্ট করুন:

import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id

ডিভাইস এপিআই-এর সাথে নির্দিষ্ট ডিভাইসের ধরন বা বৈশিষ্ট্য ব্যবহার করতে হলে, সেগুলোকে আলাদাভাবে ইম্পোর্ট করতে হবে।

উদাহরণস্বরূপ, Matter On/Off ট্রেইট এবং On/Off প্লাগ-ইন ইউনিট ডিভাইস টাইপ ব্যবহার করতে, আপনার অ্যাপ্লিকেশনে নিম্নলিখিত প্যাকেজগুলি ইম্পোর্ট করুন:

import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice

আরও তথ্যের জন্য, অ্যান্ড্রয়েডের ডেটা মডেল দেখুন।

ত্রুটি পরিচালনা

Home API-এর যেকোনো মেথড HomeException থ্রো করতে পারে, তাই আমরা সুপারিশ করি যে আপনি সমস্ত কলে HomeException ক্যাচ করার জন্য একটি try-catch ব্লক ব্যবহার করুন।

HomeException হ্যান্ডেল করার সময়, কী ভুল হয়েছে তা জানতে এর error.code এবং error.message ফিল্ডগুলো পরীক্ষা করুন। এর সাব-এরর কোডও থাকতে পারে, তাই getSubErrorCodes() মেথডটি কল করে ফলাফলটি যাচাই করুন।

যেকোনো অনিয়ন্ত্রিত ব্যতিক্রমের ফলে আপনার অ্যাপটি ক্র্যাশ করবে।

আরও তথ্যের জন্য, ত্রুটি পরিচালনা (Error handling ) দেখুন।

একটি উদাহরণের জন্য ‘কোনো ডিভাইসে কমান্ড পাঠান’ দেখুন।

নমুনা কল

ডিভাইসগুলির একটি তালিকা পান

একবার আপনার কাছে Structure ইনস্ট্যান্সটির একটি রেফারেন্স থাকলে, একটি devices() কল সেই স্ট্রাকচার থেকে আপনার জন্য অ্যাক্সেসযোগ্য ডিভাইসগুলির একটি Flow ফেরত দেয়:

// Get a flow of all devices accessible to the user
val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allDevices: Set<HomeDevice> = allDevicesFlow.list()

সেখান থেকে আপনি প্রতিটি ডিভাইসের অবস্থা জানতে পারবেন এবং ডিভাইসগুলোতে কমান্ড পাঠাতে পারবেন।

Home API-এর 1.8 রিলিজের সাথে, আপনি devices() মেথডের enableMultipartDevices প্যারামিটারটিকে true সেট করে প্রতিটি মাল্টিপার্ট ডিভাইসকে একটি একক ডিভাইস হিসাবে উপস্থাপন করার বিকল্প পাচ্ছেন। আরও তথ্যের জন্য Android-এ মাল্টিপার্ট ডিভাইস দেখুন।

ডিভাইসের অবস্থা পড়ুন

ডিভাইসের On/Off ট্রেইট থেকে OnOff অ্যাট্রিবিউটটি পরীক্ষা করার একটি উদাহরণ দেখুন। Home API-এর ট্রেইট ডেটা মডেল ব্যবহার করে, যেখানে এই ট্রেইটটি OnOff হিসাবে চিহ্নিত, আপনি ডিভাইস টাইপের standardTraits ক্লাসের মাধ্যমে ট্রেইট ডেটা পুনরুদ্ধার করতে পারেন:

// Assuming we have a device.
val deviceFlow = home.devices().itemFlow(myDeviceId)

val device = deviceFlow.first()

// Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger
// on the specific trait changes and not the whole type.
val onOffTraitFlow: Flow<OnOff?> =
  device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged()

val onOffTrait: OnOff = onOffTraitFlow.first()!!

কোটলিন ফ্লো ফাংশন সম্পর্কে আরও জানতে distinctUntilChanged দেখুন।

একটি ট্রেইট সাবস্ক্রিপশনে স্টেট বাতিল করুন

TraitStateInvalidation ইন্টারফেসটি টার্গেট ডিভাইসের সাবস্ক্রিপশনের মাধ্যমে প্রাপ্ত কোনো স্টেটকে বাতিল করার ক্ষমতা প্রদান করে, যদি স্টেটটি সঠিকভাবে রিপোর্ট করা না হয়। স্টেট সঠিকভাবে রিপোর্ট না হওয়ার কিছু উদাহরণের মধ্যে রয়েছে Matter ট্রেইটে "C" কোয়ালিটির অ্যাট্রিবিউট ব্যবহার করা অথবা ডিভাইসের এমন কোনো ইমপ্লিমেন্টেশন যা অপ্রত্যাশিতভাবে সমস্যাটি সৃষ্টি করে।

এই API বর্তমান ট্রেইট স্টেটকে জোরপূর্বক রিড করে এবং বিদ্যমান ট্রেইট ফ্লো-এর মাধ্যমে ফলাফলটি ফেরত দেয়।

ট্রেইটটি নিন, তারপর ট্রেইটটির উপর একটি forceRead চালান:

val onOffTrait = device.?type(DimmableLightDevice)?.map{it.trait(OnOff)}.first()
onOffTrait.forceRead()

ডিভাইসের প্রকারের বৈশিষ্ট্যগুলির একটি তালিকা পান

বৈশিষ্ট্য পাঠের প্রবেশপথ হিসেবে ডিভাইসের প্রকারভেদ ব্যবহার করা উচিত, কারণ এগুলো একটি ডিভাইসকে তার কার্যকরী অংশগুলোতে (যেমন Matter প্রান্তবিন্দু) বিভক্ত করে।

এক্ষেত্রেও বৈশিষ্ট্যের সংঘর্ষের বিষয়টি বিবেচনা করা হয়, যদি কোনো ডিভাইসে দুই ধরনের ডিভাইস থাকে এবং উভয়টিরই একই বৈশিষ্ট্য থাকতে পারে। উদাহরণস্বরূপ, যদি একটি ডিভাইস একই সাথে স্পিকার এবং ডিমেবল লাইট হয়, তবে এর দুটি অন/অফ এবং দুটি লেভেল কন্ট্রোল বৈশিষ্ট্য থাকবে।

ডিমেবল লাইট ডিভাইস টাইপের জন্য উপলব্ধ বৈশিষ্ট্যগুলির তালিকা পেতে:

// Get all types available on this device. Requires the types to be part of the registry during
// SDK initialization.
val typesFlow: Flow<Set<DeviceType>> = device.types()

// Get a snapshot of all types.
val types: Set<DeviceType> = typesFlow.first()

// Get the DimmableLightDevice instance from the set of types.
val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull()

// Get all traits in the type + traits registered
val allTraits: Set<Trait> = dimmableLightDevice!!.traits()

আরেক ধরনের ট্রেইট সংঘর্ষ ঘটতে পারে যখন একটি ডিভাইসে একই নামের দুটি ট্রেইট থাকে। উদাহরণস্বরূপ, onOff স্ট্যান্ডার্ড OnOff ট্রেইটের একটি ইনস্ট্যান্সকে নির্দেশ করতে পারে, অথবা এটি প্রস্তুতকারক-সংজ্ঞায়িত OnOff ট্রেইটের একটি ইনস্ট্যান্সকে নির্দেশ করতে পারে। কোন ট্রেইটটি বোঝানো হচ্ছে সে সম্পর্কে যেকোনো সম্ভাব্য অস্পষ্টতা দূর করতে, একটি ডিভাইসের মাধ্যমে রেফারেন্স করা Trait ইনস্ট্যান্সের আগে একটি কোয়ালিফাইং নেমস্পেস থাকা উচিত। স্ট্যান্ডার্ড ট্রেইটগুলির জন্য, অর্থাৎ, যেগুলি Matter স্ট্যান্ডার্ড ক্লাস্টারের অনুরূপ, standardTraits ব্যবহার করুন। গুগল ট্রেইটগুলির জন্য, googleTraits ব্যবহার করুন।

// Accessing standard traits on the type.
val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff
val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl

প্রস্তুতকারক-নির্দিষ্ট কোনো বৈশিষ্ট্য অ্যাক্সেস করতে, সরাসরি সেটিকে উল্লেখ করুন:

// Accessing a custom trait on the type.
val customTrait = dimmableLightDevice.trait(MyCustomTrait)

একটি নির্দিষ্ট বৈশিষ্ট্য সহ ডিভাইসগুলির একটি তালিকা পান

কোটলিনের filter ফাংশনটি এপিআই কলগুলোকে আরও পরিমার্জিত করতে ব্যবহার করা যায়। উদাহরণস্বরূপ, বাড়ির এমন ডিভাইসগুলোর একটি তালিকা পেতে, যেগুলোর সবকটিতেই On/Off ট্রেইট রয়েছে:

// Get all devices that support OnOff
val onOffDevices: Flow<List<HomeDevice>> =
  home.devices().map { devices -> devices.filter { it.has(OnOff) } }

হোম এপিআই-তে উপলব্ধ ট্রেইটগুলির সম্পূর্ণ তালিকার জন্য Trait ইন্টারফেসটি দেখুন।

একই ধরনের ডিভাইসগুলির একটি তালিকা পান

বাড়ির সমস্ত বাতিকে প্রতিনিধিত্বকারী ডিভাইসগুলির একটি তালিকা পেতে:

// Get a list of devices with similar device types (lights)
val lightDevices =
  home.devices().map { devices ->
    devices.filter {
      it.has(DimmableLightDevice) ||
        it.has(OnOffLightDevice) ||
        it.has(ColorTemperatureLightDevice) ||
        it.has(ExtendedColorLightDevice)
    }
  }

হোম এপিআই-তে একাধিক ডিভাইস টাইপ রয়েছে যা একটি কোর ডিভাইস টাইপকে প্রতিনিধিত্ব করতে পারে। উদাহরণস্বরূপ, কোনো "লাইট" ডিভাইস টাইপ নেই। এর পরিবর্তে, চারটি ভিন্ন ডিভাইস টাইপ রয়েছে যা একটি লাইটকে প্রতিনিধিত্ব করতে পারে, যেমনটি পূর্ববর্তী উদাহরণে দেখানো হয়েছে। এই কারণে, একটি হোমের উচ্চ-স্তরের ডিভাইস টাইপের একটি পূর্ণাঙ্গ চিত্র পেতে হলে, ফিল্টার করা ফ্লো-তে একাধিক ডিভাইস টাইপ অন্তর্ভুক্ত করতে হবে।

হোম এপিআই-গুলিতে উপলব্ধ ডিভাইসের প্রকারগুলির সম্পূর্ণ তালিকার জন্য DeviceType ইন্টারফেসটি দেখুন।

একটি ডিভাইসের জন্য ভেন্ডর আইডি বা প্রোডাক্ট আইডি সংগ্রহ করুন।

BasicInformation ট্রেইটটিতে একটি ডিভাইসের জন্য ভেন্ডর আইডি, প্রোডাক্ট আইডি, প্রোডাক্টের নাম এবং সিরিয়াল নম্বরের মতো তথ্য অন্তর্ভুক্ত থাকে:

// Get device basic information. All general information traits are on the RootNodeDevice type.
val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!!
println("vendorName ${basicInformation.vendorName}")
println("vendorId ${basicInformation.vendorId}")
println("productId ${basicInformation.productId}")

ডিভাইস প্রস্তুতকারকদের জন্য ক্লাউড-টু-ক্লাউড ডিভাইস শনাক্তকরণ

আপনি যদি একজন ডিভাইস নির্মাতা হন এবং Cloud-to-cloud ডিভাইস তৈরি করেন, তাহলে BasicInformation ট্রেইটের মাধ্যমে আপনার Cloud-to-cloud ডিভাইসগুলোকে শনাক্ত করার জন্য, সেগুলোর SYNC রেসপন্সে এই স্ট্রিং ফিল্ডগুলো অন্তর্ভুক্ত করতে পারেন:

  • Connectivity Standards Alliance (Alliance) কর্তৃক ইস্যুকৃত ভেন্ডর আইডি: "matterOriginalVendorId": "0xfff1",

  • একটি পণ্য শনাক্তকারী যা কোনো বিক্রেতার পণ্যকে অনন্যভাবে শনাক্ত করে: "matterOriginalProductId": "0x1234",

  • ডিভাইসটির জন্য একটি অনন্য শনাক্তকারী, যা প্রস্তুতকারক-নির্দিষ্ট পদ্ধতিতে তৈরি করা হয়: "matterUniqueId": "matter-device-id",

এই স্ট্রিং ফিল্ডগুলিতে তথ্য প্রবেশ করানোর সময়, আপনার Matter ভেন্ডর এবং প্রোডাক্ট আইডি থাকলে সেগুলি ব্যবহার করুন। আপনি যদি Alliance সদস্য না হন এবং আপনাকে এই আইডিগুলি বরাদ্দ করা না হয়ে থাকে, তাহলে আপনি matterOriginalVendorId এবং matterOriginalProductId ফিল্ডগুলি খালি রেখে শনাক্তকারী হিসাবে matterUniqueId প্রদান করতে পারেন।

উদাহরণ SYNC প্রতিক্রিয়াটিতে এই ক্ষেত্রগুলির ব্যবহার দেখানো হয়েছে:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "456",
        "type": "action.devices.types.LIGHT",
        "traits": [
          "action.devices.traits.OnOff",
          "action.devices.traits.Brightness",
          "action.devices.traits.ColorSetting",
        ],
        "willReportState": true,
        "deviceInfo": { ... },
        "matterOriginalVendorId": "0xfff1",
        "matterOriginalProductId": "0x1234",
        "matterUniqueId": "matter-device-id",
        "otherDeviceIds": [
          {
            "deviceId": "local-device-id",
          }
        ]
      }
    ]
  }
}

আরও তথ্যের জন্য, Cloud-to-cloud SYNC ডকুমেন্টেশন দেখুন।

ডিভাইস এবং বৈশিষ্ট্য মেটাডেটা

হোম এপিআই-এর ডিভাইস এবং বৈশিষ্ট্যগুলোর সাথে মেটাডেটা যুক্ত থাকে, যা একটি অ্যাপে ব্যবহারকারীর অভিজ্ঞতা পরিচালনায় সাহায্য করতে পারে।

হোম এপিআই-এর প্রতিটি ট্রেইটে একটি sourceConnectivity প্রপার্টি থাকে, যাতে ট্রেইটটির অনলাইন স্ট্যাটাস এবং লোকালিটি (লোকাল বা রিমোট রাউটিং) সম্পর্কিত তথ্য থাকে।

একটি ডিভাইসের প্রাথমিক ধরণটি পান

কিছু ডিভাইস হোম এপিআই (Home API)-এর মাধ্যমে একাধিক ডিভাইসের ধরন প্রদর্শন করতে পারে। ব্যবহারকারীরা যাতে কোনো অ্যাপে তাদের ডিভাইসের জন্য সঠিক বিকল্পগুলো (যেমন ডিভাইস নিয়ন্ত্রণ এবং প্রস্তাবিত অটোমেশন) দেখতে পান, তা নিশ্চিত করার জন্য ডিভাইসটির প্রাথমিক ডিভাইসের ধরন কী, তা যাচাই করে নেওয়া দরকারি।

প্রথমে, type() ব্যবহার করে ডিভাইসটির ধরণ(গুলি) জানুন, তারপর প্রাথমিক ধরণ(গুলি) নির্ধারণ করুন:

val types = device.types().first()
val primaryTypes = types.filter { it.metadata.isPrimaryType }

কোনো বৈশিষ্ট্য অনলাইন আছে কিনা তা পরীক্ষা করুন

একটি ট্রেইটের কানেক্টিভিটি পরীক্ষা করতে connectivityState() মেথডটি ব্যবহার করুন:

val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState

কিছু বৈশিষ্ট্য, বিশেষ করে গুগল smart home বৈশিষ্ট্যগুলো, ডিভাইসে ইন্টারনেট সংযোগ না থাকলে অফলাইন দেখাতে পারে। এর কারণ হলো, এই বৈশিষ্ট্যগুলো ক্লাউড-ভিত্তিক এবং এগুলোতে লোকাল রাউটিং নেই।

একটি ডিভাইসের সংযোগ পরীক্ষা করুন

একটি ডিভাইসের কানেক্টিভিটি আসলে ডিভাইস টাইপ লেভেলে চেক করা হয়, কারণ কিছু ডিভাইস একাধিক ডিভাইস টাইপ সাপোর্ট করে। যে স্টেটটি রিটার্ন করা হয়, তা হলো সেই ডিভাইসের সমস্ত ট্রেইটের কানেক্টিভিটি স্টেটগুলোর একটি সমন্বয়।

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

ইন্টারনেট সংযোগ না থাকলে, বিভিন্ন ধরনের ডিভাইসের ক্ষেত্রে PARTIALLY_ONLINE অবস্থা দেখা যেতে পারে। লোকাল রাউটিংয়ের কারণে Matter স্ট্যান্ডার্ড ট্রেইটগুলো অনলাইন থাকতে পারে, কিন্তু ক্লাউড-ভিত্তিক ট্রেইটগুলো অফলাইন থাকবে।

একটি ট্রেইটের নেটওয়ার্ক রাউটিং পরীক্ষা করুন

একটি ট্রেইটের অবস্থান হোম এপিআই-তেও পাওয়া যায়। dataSourceLocality নির্দেশ করে যে ট্রেইটটি দূরবর্তীভাবে (ক্লাউডের মাধ্যমে), স্থানীয়ভাবে (একটি স্থানীয় হাবের মাধ্যমে), নাকি পিয়ার-টু-পিয়ার (সরাসরি ডিভাইস থেকে ডিভাইসে, কোনো হাব ছাড়া) রাউট করা হচ্ছে।

UNSPECIFIED নামক অজানা লোকালিটি ভ্যালুটি দেখা যেতে পারে, উদাহরণস্বরূপ, যখন কোনো অ্যাপ বুট হচ্ছে এবং ডিভাইস কানেক্টিভিটির জন্য এখনও কোনো হাব বা সার্ভারে পৌঁছায়নি। এই ডিভাইসগুলো নাগালের বাইরে থাকে এবং কমান্ড বা ইভেন্ট থেকে আসা ইন্টারঅ্যাকশন রিকোয়েস্টগুলো ব্যর্থ করে দেয়। এই ধরনের ডিভাইসগুলোকে কীভাবে হ্যান্ডেল করতে হবে, তা নির্ধারণ করার দায়িত্ব ক্লায়েন্টের।

val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality

একটি ডিভাইসের জন্য নেটওয়ার্ক রাউটিং পরীক্ষা করুন

কানেক্টিভিটির মতোই, লোকালিটিও ডিভাইস টাইপ লেভেলে যাচাই করা হয়। ফেরত আসা স্টেটটি হলো সেই ডিভাইসের সমস্ত ট্রেইটের লোকালিটির একটি সমন্বয়।

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

PARTIALLY_ONLINE সংযোগের মতো একই পরিস্থিতিতে MIXED অবস্থাও পরিলক্ষিত হতে পারে: এর কিছু বৈশিষ্ট্য ক্লাউড-ভিত্তিক এবং অন্যগুলো স্থানীয়।

একটি ডিভাইসের নাম পরিবর্তন করুন

ডিভাইসের নাম পরিবর্তন করতে setName() মেথডটি কল করুন:

mixerDevice.setName("Grendel")

নাম ৬০ ইউনিকোড কোড পয়েন্ট (ক্যারেক্টার) সীমা অতিক্রম করলে তা সংক্ষিপ্ত করা হবে এবং কোনো ত্রুটি দেখানো হবে না। দীর্ঘ নাম পরিচালনার দায়িত্ব ডেভেলপারদের এবং উদাহরণস্বরূপ, তারা ব্যবহারকারীদের জানাতে চান কিনা যে নাম সংক্ষিপ্ত করা হবে, সেই সিদ্ধান্ত তারা নিতে পারেন।