Android-এ Structure API

Android-এর জন্য Home API-এর মাধ্যমে Structure API অ্যাক্সেস করা যেতে পারে। আপনার অ্যাপে এইসব প্যাকেজ ইমপোর্ট করুন:

import com.google.home.Home
import com.google.home.Id
import com.google.home.Structure

সমস্যা ম্যানেজ করা

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

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

কোনও হ্যান্ডেল না করা ব্যতিক্রমের ফলে আপনার অ্যাপ ক্র্যাশ করবে।

আরও তথ্যের জন্য, সমস্যা সমাধান দেখুন।

স্যাম্পেল কল

হোমের তালিকা পান

শুরু করার পরে, structures() কল আপনার অ্যাক্সেস করা যায় এমন স্ট্রাকচারের ফ্লো রিটার্ন করে:

// Get a flow of all structures accessible to the user
val allStructuresFlow: HomeObjectsFlow<Structure> = home.structures()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allStructures: Set<Structure> = allStructuresFlow.list()

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

অন্যথায়, রিঅ্যাক্টিভ প্রোগ্রামিংয়ের পরিবর্তে ইম্পারেটিভ প্রোগ্রামিংয়ের প্রয়োজন হলে, টার্মিনাল ফ্লো অপারেটর ব্যবহার করা যেতে পারে:

val everyStructure = withTimeout(5000) { home.structures().first { it.isNotEmpty() } }

এই কলটি ফ্লোর মাধ্যমে স্ট্রাকচারের একটি সঠিক তালিকা আসার জন্য অপেক্ষা করে এবং অ্যাপ-নির্ধারিত টাইমআউটের মধ্যে তালিকাটি না পেলে টাইমআউট হয়ে যায়।

স্ট্রাকচার প্রপার্টি পান

স্ট্রাকচারের তালিকা হাতে থাকলে, আপনি সেগুলির জন্য প্রপার্টি অ্যাক্সেস করতে পারবেন:

// Get a flow on a structure. Flow emits new values on structure metadata changes: name.
val structureFlow: Flow<Structure> = home.structures().itemFlow(myStructureId)

// Get a snapshot of the structure.
val structure: Structure = structureFlow.first()

// Get structure properties
println("id ${structure.id}")
println("name ${structure.name}")

নাম দিয়ে কোনও স্ট্রাকচার খুঁজুন

আপনি যদি কোনও স্ট্রাকচারের নাম জানেন, তাহলে আপনি name প্রপার্টি ব্যবহার করেও এটি অ্যাক্সেস করতে পারবেন:

val myHome = home.structures().list().first { it.name == "My home" }

সেখান থেকে, প্রতিটি স্ট্রাকচারের জন্য প্রপার্টি, রুম ও ডিভাইস অ্যাক্সেস করা যায়।

একাধিক স্ট্রাকচার নিয়ে কাজ করা

একাধিক স্ট্রাকচার ব্যবহার করতে, প্রতিটি স্ট্রাকচারের জন্য আলাদা রেফারেন্স পান:

var structure1: Structure? = null
var structure2: Structure? = null

try {
  structure1 = home.structures().list().firstOrNull { it.name == "Main House" }
} catch (e: HomeException) {
  // Code for handling the exception
}
try {
  structure2 = home.structures().list().firstOrNull { it.name == "Guest Cottage" }
} catch (e: HomeException) {
  // Code for handling the exception
}

রুমের তালিকা পান

স্ট্রাকচার হাতে থাকলে, আপনি রুমের তালিকা পেতে এবং সেগুলির জন্য প্রপার্টি অ্যাক্সেস করতে পারবেন:

val allRoomsFlow: HomeObjectsFlow<Room> = structure.rooms()
val allRooms: Set<Room> = allRoomsFlow.list()
val room: Room = allRooms.first()

println("id ${room.id}")
println("name ${room.name}")

রুম তৈরি করুন

নতুন রুম তৈরি করতে:

val testName = "Test Room Name"
val newRoom: Room = structure.createRoom(testName)

রুম মুছে দেওয়া

অথবা, আপনি অন্যভাবেও রুম মুছে দিতে পারেন:

val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull()
    structure.deleteRoom(roomToDelete!!)

এছাড়াও, আপনি শুধু আইডি ব্যবহার করে রুম মুছে দিতে পারবেন:

val roomToDelete1 = allRooms.filter { it.id == testRoomId }.firstOrNull()
structure.deleteRoom(roomToDelete1!!)

ডিভাইস সহ কোনও রুম মুছে দেওয়া হলে, ডিভাইসগুলি স্ট্রাকচারে থেকে যাবে কিন্তু কোনও রুমে আর অ্যাসাইন করা থাকবে না।

ডিভাইস অন্য রুমে সরানো

আপনার কাছে স্ট্রাকচার থাকলে, আপনি সেই স্ট্রাকচারের মধ্যে ডিভাইসটি অন্য রুমে সরাতে পারবেন:

val room2 = structure.rooms().get(Id("room_id_other_structure"))
    val device1 = structure.devices().get(Id("device_id1"))
    structure.moveDevicesToRoom(room2!!, listOf(device1!!))

আপনার কাছে শুধু ডিভাইস ও রুম আইডি থাকলে, আপনি ডিভাইসও সরাতে পারবেন:

structure.moveDevicesToRoom(Id("room_id_other_structure"), listOf(Id("device_id1")))

রুমের নাম পরিবর্তন করা

রুমের নাম পরিবর্তন করতে setName() পদ্ধতি কল করুন:

livingRoom.setName("Living Room")

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

Google Home ইকোসিস্টেমে, বেশিরভাগ ডিভাইসের ধরনের জন্য, ব্যবহারকারীরা একবারে সেই ধরনের সব ডিভাইসের জন্য অনুমতি দিতে পারেন। লক, ক্যামেরা বা কলিং বেলের মতো সংবেদনশীল বা বিধিনিষেধযুক্ত ডিভাইসের ক্ষেত্রে, ব্যবহারকারীদের অবশ্যই আলাদাভাবে সেগুলির জন্য অনুমতি দিতে হবে।

কোনও ব্যবহারকারী সংবেদনশীল বা সীমাবদ্ধ ডিভাইসের ধরন অ্যাক্সেস করার অনুমতি দিয়েছেন কিনা তা নির্ধারণ করতে, স্ট্রাকচার-লেভেল consentedDeviceTypes() ফাংশন ব্যবহার করুন:

import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Example of how an app may monitor which device types have been granted access by a user.
 */
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
    // Obtain the flow of consented device type factories
    val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
        structure.consentedDeviceTypes()

    myScope.launch {
        consentedTypesFlow.collect { consentedSet ->
            // Check if the user has consented to share a specific restricted
            // type, such as a Doorbell or Camera.
            val hasCameraAccess = consentedSet.any {
                it.toString() == "matter.google.type.GoogleDoorbellDevice"
            }

            if (hasCameraAccess) {
                // Enable features that require camera access
            } else {
                // Inform the user or disable camera-specific features
            }
        }
    }
}

ডিভাইস গ্রুপ

ডিভাইস গ্রুপ বলতে একটি স্ট্রাকচারের মধ্যে ব্যবহারকারীর দ্বারা সংজ্ঞায়িত ডিভাইসের সংগ্রহকে বোঝায়। Google পরিষেবায় গ্রুপ মেম্বারশিপ বজায় রাখা হয় এবং স্ট্রাকচারের অন্যান্য মেম্বার ও স্ট্রাকচারে অ্যাক্সেস আছে এমন অন্যান্য অ্যাপের কাছে তা দৃশ্যমান হয়।

ফিজিক্যাল রুমের মতো, ডিভাইস গ্রুপ একটি স্ট্রাকচারের অন্তর্গত। তবে, রুমের মতো নয়, ডিভাইস গ্রুপ হল লজিক্যাল গ্রুপিং। একটি ডিভাইস একই সাথে একাধিক ডিভাইস গ্রুপের অংশ হতে পারে। ডিভাইস গ্রুপে সর্বাধিক ১০০টি ডিভাইস থাকতে পারে।

ডিভাইস গ্রুপ DeviceGroup এন্টিটি দ্বারা প্রতিনিধিত্ব করা হয়, যা HomeDevice থেকে আলাদা। ডিভাইস গ্রুপে কোয়েরি ও ইন্টার‍্যাক্ট করতে, FactoryRegistry শুরু করার সময় entityTypes তালিকায় DeviceGroup অন্তর্ভুক্ত করুন, এর সাথে Group, GroupManagement এবং GroupMembership ট্রেটও অন্তর্ভুক্ত করুন।

আপনি কোনও গ্রুপের ডিভাইসের সাথে ইন্টার‍্যাক্ট করতে পারেন, হয় সরাসরি এর মেম্বার ডিভাইসের উপর ইটারেট করে (দেখুন গ্রুপ মেম্বার ডিভাইসের সাথে ইন্টার‍্যাক্ট করুন) অথবা DeviceGroup-এ ডিভাইসের ধরনের অংশকে টার্গেট করে (দেখুন ডিভাইস গ্রুপ কন্ট্রোল করুন)।

ডিভাইস গ্রুপের তালিকা পান

কোনও স্ট্রাকচারের সব ডিভাইস গ্রুপ দেখতে, home.entities(DeviceGroup) কল করুন এবং স্ট্রাকচারের আইডি অনুযায়ী ফিল্টার করুন:

home.entities(DeviceGroup).collect { allGroups ->
  val structureGroups = allGroups.filter { it.structureId == structure.id }
  for (group in structureGroups) {
    val groupName = group.trait(Group)?.Name
    println("Found group: $groupName with ID: ${group.id.id}")
  }
}

গ্রুপ মেম্বারের ডিভাইসের সাথে ইন্টার‍্যাক্ট করা

group.devices()-এর মাধ্যমে কোনও গ্রুপের মেম্বার ডিভাইসের উপর ইটারেট করলে, আপনি প্রত্যেক মেম্বারের উপর সূক্ষ্ম কন্ট্রোল পান, একটি অনুরোধে কমান্ড ব্যাচ করতে পারেন এবং মেম্বারদের মধ্যে অ্যাট্রিবিউট অ্যাগ্রিগেট বা লিখতে পারেন।

যেমন, কোনও গ্রুপের সব মানানসই মেম্বারদের মধ্যে কোনও বৈশিষ্ট্যের জন্য কমান্ড সহ একটি ব্যাচ করা অনুরোধ পাঠাতে:

val members = group.devices(enableMultipartDevices = true).first()
val onOffTraits = members.mapNotNull { device ->
  device.partOrNull(OnOffLightDevice).first()?.standardTraits?.onOff
}

val responses = home.sendBatchedCommands {
  onOffTraits.map { onOff ->
    add(onOff.onBatchable())
  }
}

for (response in responses) {
  response.getOrThrow()
}

এছাড়াও, আপনি কোনও গ্রুপের সব ম্যাচিং মেম্বার ডিভাইস জুড়ে অ্যাট্রিবিউট আপডেট করতে পারবেন (যেমন, সব DimmableLightDevice মেম্বারে onTransitionTime থেকে 1u-এ সেট করা) এবং সময়সীমার মধ্যে সম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে পারবেন:

val members = group.devices(enableMultipartDevices = true).first()

withTimeout(5.seconds) {
  members.map { device ->
    async {
      val light = device.partOrNull(DimmableLightDevice).first()
      val levelControl = light?.standardTraits?.levelControl
      if (
        levelControl?.supports(
          LevelControl.Attribute.onTransitionTime
        ) == true
      ) {
        levelControl.update { setOnTransitionTime(1u) }
      }
    }
  }.awaitAll()
}

গ্রুপের মেম্বারদের মধ্যে কোনও অ্যাট্রিবিউট অ্যাগ্রিগেট করতে, যেমন গ্রুপের সব কালার টেম্পারেচার লাইটের মধ্যে ন্যূনতম colorTempPhysicalMaxMireds খোঁজা:

val members = group.devices(enableMultipartDevices = true).first()
val minMaxMireds: UShort? = members.mapNotNull { device ->
  val light = device.partOrNull(ColorTemperatureLightDevice).first()
  light?.standardTraits?.colorControl?.colorTempPhysicalMaxMireds
}.minOrNull()

ডিভাইস গ্রুপ তৈরি করা

ডিভাইস গ্রুপ তৈরি করতে স্ট্রাকচারে GroupManagement ব্যবহার করুন:

val groupManagement = structure.trait(GroupManagementTrait)
val response = groupManagement?.createUserDefinedGroup(
  name = "Living room lights",
  memberDeviceObjectIds = listOf(light1.id.id, light2.id.id)
)

গ্রুপ মেম্বারশিপ ম্যানেজ করা

আগে থেকে থাকা গ্রুপে মেম্বার যোগ করতে:

structure.trait(GroupManagementTrait)?.addGroupMembers(
  groupObjectId = group.id.id,
  memberDeviceObjectIds = listOf(light3.id.id)
)

গ্রুপ থেকে মেম্বারদের সরাতে:

structure.trait(GroupManagementTrait)?.removeGroupMembers(
  groupObjectId = group.id.id,
  memberDeviceObjectIds = listOf(light1.id.id)
)

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

ডিভাইস গ্রুপের নাম পরিবর্তন করতে, গ্রুপের GroupTrait-এ নামের অ্যাট্রিবিউট আপডেট করুন:

group.trait(GroupTrait)?.update {
  name = "Movie corner"
}

ডিভাইস গ্রুপ মুছে দেওয়া

কোনও স্ট্রাকচার থেকে ডিভাইস গ্রুপ মুছে দিতে:

structure.trait(GroupManagementTrait)?.deleteGroup(
  groupObjectId = group.id.id
)

অটোমেশন

Automation API-এর এন্ট্রি পয়েন্ট হল স্ট্রাকচার। Home API-তে অটোমেশন সম্পর্কে আরও জানতে, Android-এ অটোমেশন API-এর ওভারভিউ দেখুন।