অ্যান্ড্রয়েডে ডিভাইস নিয়ন্ত্রণ করুন

একটি বৈশিষ্ট্য একটি কমান্ড সমর্থন করে কিনা পরীক্ষা করুন

একটি বৈশিষ্ট্য কমান্ডের জন্য সমর্থনও পরীক্ষা করা যেতে পারে। এছাড়াও একটি নির্দিষ্ট ডিভাইসের জন্য একটি কমান্ড সমর্থিত কিনা তা পরীক্ষা করতে বৈশিষ্ট্য-স্তরের supports ফাংশন ব্যবহার করুন।

উদাহরণস্বরূপ, অন/অফ বৈশিষ্ট্যের toggle কমান্ডের একটি ডিভাইসের সমর্থন পরীক্ষা করতে:

// Check if the OnOff trait supports the toggle command.
if (onOffTrait.supports(OnOff.Command.Toggle)) {
  println("onOffTrait supports toggle command")
} else {
  println("onOffTrait does not support stateful toggle command")
}

একটি ডিভাইসে একটি কমান্ড পাঠান

একটি কমান্ড পাঠানো একটি বৈশিষ্ট্য থেকে একটি রাষ্ট্র বৈশিষ্ট্য পড়ার অনুরূপ। ডিভাইসটি চালু বা বন্ধ করতে, OnOff বৈশিষ্ট্যের টগল কমান্ডটি ব্যবহার করুন, যা Google Home ইকোসিস্টেম ডেটা মডেলে toggle() হিসাবে সংজ্ঞায়িত করা হয়েছে। এই পদ্ধতিটি onOff true হলে false পরিবর্তন করে, অথবা false হলে true পরিবর্তন করে:

// Calling a command on a trait.
try {
  onOffTrait.toggle()
} catch (e: HomeException) {
  // Code for handling the exception
}

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

বিকল্পভাবে, স্পষ্টভাবে স্টেট সেট করতে off() বা on() কমান্ডগুলি ব্যবহার করুন:

onOffTrait.off()
onOffTrait.on()

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

পরামিতি সহ একটি কমান্ড পাঠান

কিছু কমান্ড পরামিতি ব্যবহার করতে পারে, যেমন OnOff বা LevelControl বৈশিষ্ট্যে:

// Turn off the light using the DyingLight effect.
onOffTrait.offWithEffect(
  effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight,
  effectVariant = 0u,
)
// Change the brightness of the light to 50%
levelControlTrait.moveToLevel(
  level = 127u.toUByte(),
  transitionTime = null,
  optionsMask = LevelControlTrait.OptionsBitmap(),
  optionsOverride = LevelControlTrait.OptionsBitmap(),
)

কিছু কমান্ডের ঐচ্ছিক আর্গুমেন্ট থাকে, যা প্রয়োজনীয় আর্গুমেন্টের পরে আসে।

উদাহরণস্বরূপ, FanControl বৈশিষ্ট্যের জন্য step কমান্ডের দুটি ঐচ্ছিক আর্গুমেন্ট রয়েছে:

val fanControlTraitFlow: Flow<FanControl?> =
  device.type(FanDevice).map { it.standardTraits.fanControl }.distinctUntilChanged()

val fanControl = fanControlTraitFlow.firstOrNull()

// Calling a command with optional parameters not set.
fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase)

// Calling a command with optional parameters.
fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) { wrap = true }

একটি বৈশিষ্ট্য একটি বৈশিষ্ট্য সমর্থন করে কিনা পরীক্ষা করুন

কিছু ডিভাইস একটি Matter বৈশিষ্ট্য সমর্থন করতে পারে, কিন্তু একটি নির্দিষ্ট বৈশিষ্ট্য নয়। উদাহরণস্বরূপ, একটি Cloud-to-cloud ডিভাইস যা Matter ম্যাপ করা হয়েছিল তা প্রতিটি Matter অ্যাট্রিবিউটকে সমর্থন নাও করতে পারে। এই ধরনের কেসগুলি পরিচালনা করতে, বৈশিষ্ট্য-স্তরের supports ফাংশন এবং বৈশিষ্ট্যের Attribute এনাম ব্যবহার করুন যে বৈশিষ্ট্যটি একটি নির্দিষ্ট ডিভাইসের জন্য সমর্থিত কিনা তা পরীক্ষা করতে।

উদাহরণস্বরূপ, একটি ডিভাইসের অন/অফ বৈশিষ্ট্যের onOff বৈশিষ্ট্যের সমর্থন পরীক্ষা করতে:

// Check if the OnOff trait supports the onOff attribute.
if (onOffTrait.supports(OnOff.Attribute.onOff)) {
  println("onOffTrait supports onOff state")
} else {
  println("onOffTrait is for a command only device!")
}

কিছু বৈশিষ্ট্য Matter স্পেসিফিকেশন বা Cloud-to-cloud smart home স্কিমাতে বাতিলযোগ্য। এই অ্যাট্রিবিউটগুলির জন্য, আপনি নির্ধারণ করতে পারেন যে অ্যাট্রিবিউট দ্বারা প্রত্যাবর্তিত একটি নাল ডিভাইসটি সেই মানটি রিপোর্ট না করার কারণে, অথবা যদি অ্যাট্রিবিউটের মানটি আসলে null হয় , supports ছাড়াও isNullable ব্যবহার করে:

// Check if a nullable attribute is set or is not supported.
if (onOffTrait.supports(OnOff.Attribute.startUpOnOff)) {
  // The device supports startupOnOff, it is safe to expect this value in the trait.
  if (OnOff.Attribute.startUpOnOff.isNullable && onOffTrait.startUpOnOff == null) {
    // This value is nullable and set to null. Check the specification as to
    // what null in this case means
    println("onOffTrait supports startUpOnOff and it is null")
  } else {
    // This value is nullable and set to a value.
    println("onOffTrait supports startUpOnOff and it is set to ${onOffTrait.startUpOnOff}")
  }
} else {
  println("onOffTrait does not support startUpOnOff!")
}

বৈশিষ্ট্য বৈশিষ্ট্য আপডেট করুন

আপনি যদি একটি প্রদত্ত অ্যাট্রিবিউটের মান পরিবর্তন করতে চান এবং বৈশিষ্ট্যের কোনো কমান্ড তা করে না, তাহলে অ্যাট্রিবিউটটি তার মান স্পষ্টভাবে সেট করা সমর্থন করতে পারে।

একটি বৈশিষ্ট্যের মান পরিবর্তন করা যাবে কিনা তা নির্ভর করে দুটি বিষয়ের উপর:

  • বৈশিষ্ট্য লিখনযোগ্য?
  • একটি বৈশিষ্ট্য কমান্ড পাঠানোর একটি পার্শ্ব প্রতিক্রিয়া হিসাবে বৈশিষ্ট্যের মান পরিবর্তন হতে পারে?

বৈশিষ্ট্য এবং তাদের বৈশিষ্ট্যগুলির জন্য রেফারেন্স ডকুমেন্টেশন এই তথ্য প্রদান করে।

অতএব, বৈশিষ্ট্যগুলির সংমিশ্রণগুলি নির্দেশ করে যে কীভাবে একটি বৈশিষ্ট্যের মান পরিবর্তন করা যেতে পারে:

  • শুধুমাত্র পঠনযোগ্য এবং অন্যান্য কমান্ড দ্বারা প্রভাবিত হয় না । এর মানে হল যে অ্যাট্রিবিউটের মান পরিবর্তন হয় না। উদাহরণস্বরূপ, Switch বৈশিষ্ট্যের currentPosition বৈশিষ্ট্য

  • শুধুমাত্র পঠনযোগ্য এবং অন্যান্য কমান্ড দ্বারা প্রভাবিত । এর মানে হল যে অ্যাট্রিবিউটের মান পরিবর্তন করার একমাত্র উপায় হল একটি কমান্ড পাঠানোর ফলে। উদাহরণ স্বরূপ, LevelControl Matter বৈশিষ্ট্যের currentLevel অ্যাট্রিবিউটটি শুধুমাত্র পঠনযোগ্য, তবে এর মানটি moveToLevel মতো কমান্ড দ্বারা পরিবর্তিত হতে পারে।

  • লেখার যোগ্য এবং অন্যান্য কমান্ড দ্বারা প্রভাবিত হয় না । এর মানে হল যে আপনি বৈশিষ্ট্যের update ফাংশন ব্যবহার করে সরাসরি অ্যাট্রিবিউটের মান পরিবর্তন করতে পারেন, কিন্তু এমন কোনো কমান্ড নেই যা অ্যাট্রিবিউটের মানকে প্রভাবিত করবে। উদাহরণস্বরূপ, DoorLock বৈশিষ্ট্যের WrongCodeEntryLimit বৈশিষ্ট্য

  • লেখার যোগ্য এবং অন্যান্য কমান্ড দ্বারা প্রভাবিত . এর মানে হল যে আপনি বৈশিষ্ট্যের update ফাংশন ব্যবহার করে সরাসরি অ্যাট্রিবিউটের মান পরিবর্তন করতে পারেন এবং কমান্ড পাঠানোর ফলে অ্যাট্রিবিউটের মান পরিবর্তন হতে পারে। উদাহরণ স্বরূপ, Thermostat বৈশিষ্ট্যের occupiedCoolingSetpoint এট্রিবিউট লেখা হতে পারে কিন্তু setpointRaiseLower কমান্ডের সাথে আপডেট করা যেতে পারে।

একটি বৈশিষ্ট্যের মান পরিবর্তন করতে আপডেট ফাংশন ব্যবহার করার উদাহরণ

এই উদাহরণটি দেখায় কিভাবে স্পষ্টভাবে DoorLockTrait.WrongCodeEntryLimit অ্যাট্রিবিউটের মান সেট করতে হয়।

একটি বৈশিষ্ট্যের মান সেট করতে, বৈশিষ্ট্যের update ফাংশনটি কল করুন এবং এটিকে একটি মিউটেটর ফাংশন পাস করুন যা নতুন মান সেট করে। বৈশিষ্ট্যটি একটি বৈশিষ্ট্যকে সমর্থন করে কিনা তা প্রথমে যাচাই করা একটি ভাল অভ্যাস।

যেমন:

    var doorLockDevice = home.devices().list().first { device -> device.has(DoorLock) }

    val traitFlow: Flow<DoorLock?> =
      doorLockDevice.type(DoorLockDevice).map { it.standardTraits.doorLock }.distinctUntilChanged()

    val doorLockTrait: DoorLock = traitFlow.first()!!

    if (doorLockTrait.supports(DoorLock.Attribute.wrongCodeEntryLimit)) {
      val unused = doorLockTrait.update { setWrongCodeEntryLimit(3u) }
    }

একবারে একাধিক কমান্ড পাঠান

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

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

একটি ব্যাচে কমান্ড পাঠানো ডিভাইসগুলিকে একযোগে ক্রিয়া সম্পাদন করতে দেয়, যা আসলে সম্ভব হয় না যখন কমান্ডগুলি পৃথক অনুরোধে ক্রমিকভাবে পাঠানো হয়। ব্যাচড কমান্ড ব্যবহার করে অর্জিত আচরণ ডেভেলপারকে পূর্বনির্ধারিত সমষ্টিগত অবস্থার সাথে মেলে ডিভাইসের একটি গ্রুপের অবস্থা সেট করতে দেয়।

ব্যাচিং এপিআই ব্যবহার করুন

ব্যাচিং এপিআই এর মাধ্যমে কমান্ড আহ্বান করার সাথে জড়িত তিনটি মৌলিক পদক্ষেপ রয়েছে:

  1. Home.sendBatchedCommands() পদ্ধতি ব্যবহার করুন।
  2. sendBatchedCommands() ব্লকের মূল অংশের মধ্যে, ব্যাচে অন্তর্ভুক্ত করা কমান্ডগুলি নির্দিষ্ট করুন।
  3. প্রেরিত কমান্ডের ফলাফলগুলি পরীক্ষা করে দেখুন যে তারা সফল বা ব্যর্থ হয়েছে কিনা।

sendBatchedCommands() পদ্ধতি ব্যবহার করুন

Home.sendBatchedCommands() পদ্ধতিতে কল করুন। পর্দার আড়ালে, এই পদ্ধতিটি একটি বিশেষ ব্যাচ প্রসঙ্গে একটি ল্যাম্বডা অভিব্যক্তি সেট আপ করে।

home.sendBatchedCommands() {

ব্যাচ কমান্ড নির্দিষ্ট করুন

sendBatchedCommands() ব্লকের বডির মধ্যে, ব্যাচযোগ্য কমান্ডগুলিকে পপুলেট করুন। ব্যাচযোগ্য কমান্ডগুলি বিদ্যমান ডিভাইস API কমান্ডের "ছায়া" সংস্করণ যা একটি ব্যাচ প্রসঙ্গে ব্যবহার করা যেতে পারে, এবং যোগ করা প্রত্যয় Batchable দিয়ে নামকরণ করা হয়। উদাহরণস্বরূপ, LevelControl বৈশিষ্ট্যের moveToLevel() কমান্ডের moveToLevelBatchable() নামে একটি প্রতিরূপ রয়েছে।

উদাহরণ:

  val response1 = add(command1)

  val response2 = add(command2)

ব্যাচের প্রেক্ষাপটে সমস্ত কমান্ড যুক্ত হয়ে গেলে এবং এক্সিকিউশন প্রসঙ্গ ছেড়ে চলে গেলে ব্যাচটি স্বয়ংক্রিয়ভাবে পাঠানো হয়।

প্রতিক্রিয়াগুলি DeferredResponse<T> অবজেক্টে ক্যাপচার করা হয়।

DeferredResponse<T> দৃষ্টান্তগুলি যেকোন ধরণের বস্তুতে একত্রিত করা যেতে পারে, যেমন একটি Collection বা একটি ডেটা ক্লাস যা আপনি সংজ্ঞায়িত করেছেন। আপনি প্রতিক্রিয়াগুলি একত্রিত করার জন্য যে ধরণের অবজেক্ট চয়ন করেন তা sendBatchedCommands() দ্বারা ফেরত দেওয়া হয়। উদাহরণস্বরূপ, ব্যাচ প্রসঙ্গ একটি Pair দুটি DeferredResponse উদাহরণ ফিরিয়ে দিতে পারে:

  val (response1, response2) = homeClient.sendBatchedComamnds {
    val response1 = add(someCommandBatched(...))
    val response2 = add(someOtherCommandBatched(...))
    Pair(response1, response2)
  }

বিকল্পভাবে, ব্যাচ প্রসঙ্গ একটি কাস্টম ডেটা ক্লাসে DeferredResponse উদাহরণগুলি ফিরিয়ে দিতে পারে:

  // Custom data class
  data class SpecialResponseHolder(
    val response1: DeferredResponse<String>,
    val response2: DeferredResponse<Int>,
    val other: OtherResponses
  )
  data class OtherResponses(...)

প্রতিটি প্রতিক্রিয়া পরীক্ষা করুন

sendBatchedCommands() ব্লকের বাইরে, সংশ্লিষ্ট কমান্ড সফল হয়েছে নাকি ব্যর্থ হয়েছে তা নির্ধারণ করতে প্রতিক্রিয়াগুলি পরীক্ষা করুন। এটি DeferredResponse.getOrThrow() কল করে করা হয়, যা হয়: - কার্যকর করা কমান্ডের ফলাফল প্রদান করে, - অথবা, যদি ব্যাচ স্কোপ সম্পূর্ণ না হয় বা কমান্ডটি ব্যর্থ হয়, একটি ত্রুটি ছুড়ে দেয়।

আপনি শুধুমাত্র sendBatchedCommands() lambda সুযোগের বাইরে ফলাফল পরীক্ষা করা উচিত।

উদাহরণ

বলুন আপনি এমন একটি অ্যাপ তৈরি করতে চেয়েছিলেন যা একটি 'শুভ রাত্রি' দৃশ্য সেট আপ করতে ব্যাচিং API ব্যবহার করে যা রাতের জন্য বাড়ির সমস্ত ডিভাইস কনফিগার করে, যখন সবাই ঘুমিয়ে থাকে। এই অ্যাপের আলো নিভিয়ে সামনের ও পিছনের দরজা লক করা উচিত।

এখানে টাস্কের কাছে যাওয়ার একটি উপায় রয়েছে:

val lightDevices: List<OnOffLightDevice>
val doorlockDevices: List<DoorLockDevice>

// Send all the commands
val responses: List<DeferredResponse<Unit>> = home.sendBatchedCommands {
  // For each light device, send a Batchable command to turn it on
  val lightResponses: List<DeferredResponse<Unit>> = lightDevices.map { lightDevice ->
    add(lightDevice.standardTraits.onOff.onBatchable())
  }

  // For each doorlock device, send a Batchable command to lock it
  val doorLockResponse: List<DeferredResponse<Unit>> = doorlockDevices.map { doorlockDevice ->
    add(doorlockDevice.standardTraits.doorLock.lockDoorBatchable())
  }

  lightResponses + doorLockResponses
}

// Check that all responses were successful
for (response in responses) {
  response.getOrThrow()
}