Android-এর জন্য ডোরবেল ডিভাইস গাইড

ডোরবেল ডিভাইসের ধরন তিনটি ট্রেট ব্যবহার করে প্রয়োগ করা হয়: PushAvStreamTransport, যা পুশ-ভিত্তিক প্রোটোকল ব্যবহার করে অডিও ও ভিডিও স্ট্রিম ট্রান্সপোর্ট ম্যানেজ করে, WebRtcLiveView, যা লাইভ স্ট্রিম ও টকব্যাক কন্ট্রোল করার ক্ষমতা প্রদান করে এবং CameraSnapshot, যা ক্যাশে করা প্রিভিউ স্ন্যাপশট ও লাইভ স্ন্যাপশট ক্যাপচার প্রদান করে।

কোনও ফিচার ব্যবহার করার আগে বা অ্যাট্রিবিউট আপডেট করার চেষ্টা করার আগে সবসময় ডিভাইসের জন্য অ্যাট্রিবিউট ও কমান্ড কাজ করে কিনা তা চেক করে নিন। আরও তথ্যের জন্য Android-এ ডিভাইস কন্ট্রোল করুন লিঙ্ক দেখুন।

Home API ডিভাইসের ধরন বৈশিষ্ট্য Kotlin Sample App ব্যবহারের ক্ষেত্র

কলিং বেল

GoogleDoorbellDevice

home.matter.6006.types.0113

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

প্রয়োজনীয় ট্রেড
     google PushAvStreamTransport
     google WebRtcLiveView

ডোরবেল

ডিভাইস সম্পর্কে প্রাথমিক তথ্য পাওয়া

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

BasicInformation ট্রেটে ভেন্ডরের নাম, ভেন্ডর আইডি, প্রোডাক্ট আইডি, প্রোডাক্টের নাম (মডেল সংক্রান্ত তথ্য সহ) এবং ডিভাইসের সফ্টওয়্যার ভার্সনের মতো তথ্য থাকে:

// Get device basic information. All general information traits are on the RootNodeDevice type.
    device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation ->
        println("vendorName ${basicInformation.vendorName}")
        println("vendorId ${basicInformation.vendorId}")
        println("productId ${basicInformation.productId}")
        println("productName ${basicInformation.productName}")
        println("softwareVersion ${basicInformation.softwareVersion}")
    }

সিরিয়াল নম্বর পাওয়া

ডিভাইসের সিরিয়াল নম্বর পেতে, ExtendedBasicInformation ট্রেটের GetSerialNumber কমান্ড ব্যবহার করুন। এই উদাহরণে serialNumber নামের ভেরিয়েবলে সিরিয়াল নম্বর সেভ করা দেখানো হয়েছে:

val basicInfo: ExtendedBasicInformation = device.getTrait(ExtendedBasicInformation)
val serialNumber = basicInfo.getSerialNumber().serialNumber

দ্রুত উত্তর

দ্রুত উত্তর ফিচার ব্যবহারকারীকে ডোরবেল ডিভাইসে আগে থেকে লেখা মেসেজ পাঠানোর সুবিধা দেয়।

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

PresetMessage ট্রেটের মাধ্যমে 'দ্রুত উত্তর' প্রয়োগ করা হয়।

প্রিসেট মেসেজ চালানো

প্রিসেট মেসেজ চালাতে, playPresetMessage মেথড কল করুন এবং availablePhraseTypes প্রপার্টিতে পাওয়া স্ট্রিং ভ্যালুগুলির মধ্যে একটি পাস করুন।

import com.google.home.HomeDevice
import com.google.home.HomeException
import com.google.home.google.GoogleDoorbellDevice
import com.google.home.google.PresetMessage
import kotlinx.coroutines.flow.first

suspend fun playDoorbellPresetMessage(device: HomeDevice, phraseTypeString: String) {
    try {
        // 1. Retrieve the first snapshot of the doorbell device type
        val doorbellDevice = device.type(GoogleDoorbellDevice).first()

        // 2. Extract the PresetMessage trait
        val presetMessageTrait = doorbellDevice.trait(PresetMessage)
        if (presetMessageTrait == null) {
            println("PresetMessage trait is not supported on this doorbell device.")
            return
        }

        // 3. (Optional) Check available phrase types supported by the device
        val availablePhrases = presetMessageTrait.availablePhraseTypes
        if (availablePhrases != null) {
            val phraseTypesList = availablePhrases.map { it.phraseType }
            println("Supported quick response phrases: $phraseTypesList")
        }

        // 4. Send the playPresetMessage command to the doorbell
        presetMessageTrait.playPresetMessage(phraseType = phraseTypeString)
        println("Preset message command sent successfully.")

    } catch (e: HomeException) {
        println("Home API error occurred: ${e.message}")
    } catch (e: Exception) {
        println("Unexpected failure: ${e.message}")
    }
}

যে ভাষায় বলা হবে সেটি সেট করা

LocalizationConfiguration ট্রেটের setActiveLocale পদ্ধতি ব্যবহার করে কোনও ডিভাইসের অ্যাক্টিভ স্পোকেন ল্যাঙ্গুয়েজকে নির্দিষ্ট লোকেলে (যেমন, "en_US") সেট করুন।

import java.util.Locale

// Convert underscore format (en_US) to Java Locale
fun String.toLocale(): Locale = Locale.forLanguageTag(this.replace('_', '-'))

// Setting the active language
val trait: LocalizationConfiguration = device.getTrait(LocalizationConfiguration)
val selectedLocale = "en_US" // Target locale string
trait.update {
    setActiveLocale(selectedLocale)
}

ডিভাইস ক্লাউড পরিচিতির সবচেয়ে সাম্প্রতিক সময় পাওয়া

ডিভাইসটি ক্লাউডের সাথে সবচেয়ে সম্প্রতি কখন যোগাযোগ করেছে তা জানতে, ExtendedGeneralDiagnostics ট্রেটের lastContactTimestamp অ্যাট্রিবিউট ব্যবহার করুন:

fun getLastContactTimeStamp(trait: ExtendedGeneralDiagnostics): java.time.Instant {
  val timestamp = trait.lastContactTimestamp
  return Instant.ofEpochSecond(timestamp.toLong())
}

ক্যামেরা মাউন্ট টাইপ সেটিংস

Mount বৈশিষ্ট্যে ক্যামেরা মাউন্ট সেটিংস ও স্ট্যাটাস সংক্রান্ত তথ্য থাকে। আপনি মাউন্ট স্টেট, শনাক্তকরণের ধরন এবং মাউন্ট ধরনের নামের মতো অ্যাট্রিবিউট পড়তে পারেন। এছাড়াও, ডিফল্ট মাউন্ট টাইপ কনফিগারেশন ওভাররাইড করতে আপনি Mount ট্রেড ব্যবহার করতে পারবেন।

// Get the Mount trait
val mountTrait: Mount = device.getTrait(Mount)

// Read the current mount state and detection type
val mountState = mountTrait.mountState
val mountDetectionType = mountTrait.mountDetectionType

// Read the current mount type name
val mountTypeName = mountTrait.mountTypeName

// Update the mount type override
mountTrait.update {
  setMountTypeOverride(MountTrait.MountTypeOverrideEnum.Official)
}

কোনও ডিভাইসের কানেক্টিভিটি চেক করা

ডিভাইসের কানেক্টিভিটি আসলে ডিভাইসের ধরন লেভেলে চেক করা হয় কারণ কিছু ডিভাইস একাধিক ধরনের ডিভাইসে কাজ করে। রিটার্ন করা স্টেট হল সেই ডিভাইসের সব ট্রেটের কানেক্টিভিটি স্টেটের একটি কম্বিনেশন।

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   
val doorbellConnectivity = doorbellDevice.metadata.sourceConnectivity.connectivityState

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

ডিভাইসের IP অ্যাড্রেস পাওয়া

ডিভাইসের IP অ্যাড্রেস খুঁজে পেতে, GeneralDiagnostics ট্রেটের networkInterfaces অ্যাট্রিবিউট ব্যবহার করুন। ঠিকানাগুলি বাইট অ্যারে হিসেবে রিটার্ন করা হয়, যেগুলিকে আপনি স্ট্যান্ডার্ড IPv4 বা IPv6 স্ট্রিং হিসেবে ফর্ম্যাট করতে পারবেন:

val ipAddresses =
  trait.networkInterfaces?.flatMap { networkInterface ->
    (networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
      try {
        java.net.InetAddress.getByAddress(bytes).hostAddress
      } catch (e: java.net.UnknownHostException) {
        null
      }
    }
  } ?: emptyList()

লাইভ স্ট্রিম শুরু করা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

লাইভ স্ট্রিম শুরু করতে, সেশন বিবরণ প্রোটোকল (SDP) স্ট্রিং WebRtcLiveView ট্রেডের startLiveView() পদ্ধতিতে পাঠান, যা তিনটি ভ্যালু সহ একটি WebRtcLiveViewTrait.StartLiveViewCommand.Response রিটার্ন করে:

  • সেশনের জন্য SDP.
  • সেকেন্ডে সেশনের সময়সীমা।
  • সেশন আইডি, যা সেশন বাড়াতে বা বন্ধ করতে ব্যবহার করা হতে পারে।
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) {
 return cameraDevice.type(GoogleDoorbellDevice).trait(WebRtcLiveView).first {
    it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE
  }

}

// Start the live view
suspend fun startCameraStream(trait: WebRtcLiveView, offerSdp: String) {
  val response = trait.startLiveView(offerSdp)
  // Response contains three fields (see below)
  return response
}
  ...

// This is used to manage the WebRTC connection
val peerConnection: RTCPeerConnection = ...

   ...

val startResponse = startCameraStream(sdp)
val answerSdp = startResponse?.answerSdp
val sessionDuration = startResponse?.liveSessionDurationSeconds
val mediaSessionId = startResponse?.mediaSessionId

peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER,
                                    answerSdp)

লাইভ স্ট্রিমের সময়সীমা বাড়ানো

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

লাইভ স্ট্রিমের একটি পূর্বনির্ধারিত সময়সীমা থাকে, যার পরে সেটি শেষ হয়ে যায়। কোনও অ্যাক্টিভ স্ট্রিমের সময়সীমা বাড়াতে, এক্সটেনশনের অনুরোধ জানানোর জন্য WebRtcLiveView.extendLiveView() পদ্ধতি ব্যবহার করুন:

// Assuming camera stream has just been started
suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) {
  delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000)
  val response = trait.extendLiveView(mediaSessionId)
  // returns how long the session will be live for
  return response.liveSessionDurationSeconds
}

টকব্যাক চালু ও বন্ধ করা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

টকব্যাক শুরু করতে, WebRtcLiveView ট্রেটের startTalkback() মেথড কল করুন। বন্ধ করতে, stopTalkback() ব্যবহার করুন।

// Make sure camera stream is on
suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) {
  if(isOn) {
    trait.startTalkback(mediaSessionId)
  } else {
    trait.stopTalkback(mediaSessionId)
  }
}

রেকর্ডিংয়ের সুবিধা চালু ও বন্ধ করা

ক্যামেরার রেকর্ডিং ক্ষমতা চালু করতে, TransportStatusEnum.Active থেকে PushAvStreamTransport ট্রেটের setTransportStatus() মেথডে পাস করুন। রেকর্ডিং করার সুবিধা বন্ধ করতে, এটি পাস করুন TransportStatusEnum.Inactive। নিচের উদাহরণে, আমরা এইসব কলকে একটি কলে র‍্যাপ করেছি যা Boolean ব্যবহার করে রেকর্ডিং ক্ষমতা টগল করে:

// Start or stop recording for all connections.
suspend fun setCameraRecording(trait: PushAvStreamTransport, isOn: Boolean) {
  if(isOn) {
    trait.setTransportStatus(TransportStatusEnum.Active)
  } else {
    trait.setTransportStatus(TransportStatusEnum.Inactive)
  }
}

ক্যামেরার রেকর্ডিং ক্ষমতা চালু বা বন্ধ করা, ক্যামেরা ভিডিও চালু বা বন্ধ করার সমান। কোনও ক্যামেরার ভিডিও চালু থাকলে, সেটি রেকর্ড করছে (ইভেন্ট ও সংশ্লিষ্ট ক্লিপের উদ্দেশ্যে)।

রেকর্ডিং করার সুবিধা বন্ধ করা থাকলে (ক্যামেরা ভিডিও বন্ধ থাকলে):

রেকর্ডিং করার সুবিধা চালু আছে কিনা তা চেক করুন

ক্যামেরার রেকর্ডিং ক্ষমতা চালু আছে কিনা তা নির্ধারণ করতে, কোনও কানেকশন অ্যাক্টিভ আছে কিনা তা চেক করুন। এটি করার জন্য নিম্নলিখিত উদাহরণে দুটি ফাংশন সংজ্ঞায়িত করা হয়েছে:

// Get the on/off state
suspend fun onOffState(pushAvStreamTransport: PushAvStreamTransport) {
  return pushAvStreamTransport
    .currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

// Check if the camera's recording capability is enabled
fun PushAvStreamTransport.recordModeActive(): Boolean {
  return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

চেক করার আরেকটি উপায় হল, কোনও প্রেডিকেট সহ findTransport() ফাংশন ব্যবহার করা:

// Fetch the current connections
suspend fun queryRecordModeState(trait: PushAvStreamTransport) {
  return trait.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

ক্যামেরা স্ন্যাপশট ফিরিয়ে আনা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

ক্যামেরা থেকে স্ট্যাটিক ছবির স্ন্যাপশট পেতে CameraSnapshot ট্রেড ব্যবহার করুন। এইসব স্ন্যাপশট বিভিন্ন পরিস্থিতিতে কাজে লাগে:

  • WebRTC লাইভ স্ট্রিম লোড হওয়ার সময় UI-তে প্লেসহোল্ডার টাইল হিসেবে।
  • ব্যবহারকারীর ইন্টার‍্যাকশনের পরে লাইভ স্ট্রিমে আপগ্রেড হওয়া একটি স্ট্যাটিক প্রিভিউ ছবি হিসেবে।
  • কাস্টম অ্যাক্টিভিটি জোন আঁকা ও কনফিগার করার জন্য ব্যাকগ্রাউন্ড ক্যানভাস হিসেবে।

CameraSnapshot ট্রেট, দ্রুত রেন্ডারিংয়ের জন্য ক্যাশে করা স্ন্যাপশট প্রয়োজন নাকি অন-ডিমান্ড লাইভ স্ন্যাপশট প্রয়োজন, তার উপর নির্ভর করে স্ন্যাপশট পাওয়ার দুটি উপায় অফার করে।

ক্যাশে করা প্রিভিউ স্ন্যাপশট পাওয়া

প্রিভিউ স্ন্যাপশট হল একটি ক্যাশে করা ছবি যা SDK ক্যামেরা চালু না করেই রিট্রিভ করতে পারে। স্ট্যাটিক ছবি পাওয়ার এটি সবচেয়ে দ্রুত পদ্ধতি এবং এটি ক্যামেরা ওভারভিউ পৃষ্ঠা বা ড্যাশবোর্ড গ্রিডের জন্য উপযুক্ত।

প্রিভিউ স্ন্যাপশট পেতে, preview_image_url trait attribute পড়ুন:

// Get a flow of the CameraSnapshot trait
val cameraSnapshotFlow: Flow<CameraSnapshot?> = cameraDevice
  .type(GoogleCameraDevice)
  .trait(CameraSnapshot)

// Get the current trait state
val cameraSnapshot = cameraSnapshotFlow.firstOrNull()
if (cameraSnapshot != null) {
  val previewImageUrl = cameraSnapshot.previewImageUrl
  // Load the preview image from the URL
} else {
  // CameraSnapshot trait not supported on this device
}

ক্যামেরার কনফিগারেশন ও অ্যাক্টিভিটির উপর নির্ভর করে, প্রিভিউ URL সাম্প্রতিক ভিডিও ফুটেজ থেকে তৈরি করা কোনও ক্যাশে করা ছবি (লেটেস্ট ভিডিও ফ্র্যাগমেন্টের প্রথম I-ফ্রেম) অথবা ক্যামেরা দ্বারা মাঝে মাঝে আপলোড করা কোনও স্ন্যাপশটের দিকে পয়েন্ট করে।

ছবির ফ্রেশনেস বোঝাতে, Google Home ক্লাউড পরিবেশিত JPEG/PNG ছবিতে X-Home-Image-Captured-At হেডার এম্বেড করে, যা UTC-তে ফর্ম্যাট করা হয়। অ্যাপে স্ন্যাপশটের বয়স দেখাতে, আপনি ক্লায়েন্ট-সাইডে এই হেডার পার্স করতে পারবেন।

চাহিদা মতো লাইভ স্ন্যাপশট পাওয়া

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

লাইভ স্ন্যাপশটের অনুরোধ করতে, getLiveSnapshot() কমান্ড ব্যবহার করুন:

try {
  val response = cameraSnapshot.getLiveSnapshot()
  val snapshotUrl = response.snapshotUrl
  // Load the live snapshot image from the URL
} catch (e: Exception) {
  Log.e("CameraSnapshot", "Failed to get live snapshot: ${e.message}")
}

স্ন্যাপশট অনুরোধ যাচাই করা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

সব স্ন্যাপশট URL সুরক্ষিত মিডিয়াকে পয়েন্ট করে এবং হোম API v2 স্কোপের জন্য OAuth 2.0 টোকেন প্রয়োজন। ছবি ডাউনলোড ও রেন্ডার করতে, OAuth টোকেনকে আপনার HTTP অনুরোধের Authorization হেডার হিসেবে বিয়ারার টোকেন হিসেবে ইনজেক্ট করতে হবে।

স্ন্যাপশট ডাউনলোড করার জন্য কীভাবে একটি সুরক্ষিত নেটওয়ার্ক অনুরোধ কনফিগার করতে হয় তা নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * Downloads a snapshot from a URL using an OAuth access token.
 */
suspend fun loadSnapshotImage(urlString: String, oauthToken: String): Bitmap? =
  withContext(Dispatchers.IO) {
    var connection: HttpURLConnection? = null
    try {
      val url = URL(urlString)
      connection = url.openConnection() as HttpURLConnection
      // 1. Configure the HTTP GET request with the Bearer token
      connection.setRequestProperty("Authorization", "Bearer $oauthToken")

      // 2. Fetch the image data
      if (connection.responseCode == HttpURLConnection.HTTP_OK) {
        connection.inputStream.use { inputStream ->
          BitmapFactory.decodeStream(inputStream)
        }
      } else {
        null
      }
    } catch (e: IOException) {
      e.printStackTrace()
      null
    } finally {
      connection?.disconnect()
    }
  }

লাইভ স্ট্রিম ম্যানেজ করা

লাইভস্ট্রিমের কোয়ালিটি অ্যাডজাস্ট করা হলে, ক্লায়েন্টের দেখার কনটেক্সটের (যেমন, ছোট প্রিভিউ টাইল, গ্রিড ভিউ বা পিকচার-ইন-পিকচার মোড দেখানোর সময় কম রেজোলিউশনে পরিবর্তন করা) উপর ভিত্তি করে ব্যান্ডউইথ ব্যবহার অপ্টিমাইজ করা যায়।

WebRtcLiveView ট্রেড ব্যবহার করে ডায়নামিক কোয়ালিটি পরিবর্তন করা, কোনও নির্দিষ্ট ক্লায়েন্টে অ্যাক্টিভ লাইভ স্ট্রিম সেশনের রেজোলিউশনকে বিশেষভাবে ম্যানেজ করে। এটি ডিভাইসে সরাসরি ডিভাইস-ওয়াইড ব্যান্ডউইথ ব্যবহার সংক্রান্ত সেটিং কনফিগার করার মতো নয়, যা সব একসাথে দেখা দর্শক এবং ক্লাউডে সেভ করা ঐতিহাসিক ভিডিও রেকর্ডিংয়ের কোয়ালিটিকে প্রভাবিত করবে।

নিচের উদাহরণ থেকে কোনও ডিভাইসের লাইভ স্ট্রিমের কোয়ালিটি কীভাবে রিট্রিভ ও আপডেট করতে হয় তা জানতে পারবেন:

  • কাজ করে এমন কোয়ালিটি বিকল্প রিট্রিভ করা: ডিভাইসে কাজ করে এমন উপলভ্য স্ট্রিমিং রেজোলিউশন পান । ডিভাইস টাইপ ফ্লোতে কোডটি WebRtcLiveView ট্রেটের supportedQualityHints অ্যাট্রিবিউট কোয়েরি করে এবং StateFlow হিসেবে কাজ করে এমন কোয়ালিটি দেখায় যেখানে QualityHint-এর একটি তালিকা থাকে (যেমন QUALITY_HINT_SD, QUALITY_HINT_HD, QUALITY_HINT_FHD, QUALITY_HINT_QHD অথবা QUALITY_HINT_UHD)।

  • লাইভ স্ট্রিমের কোয়ালিটি পরিবর্তন করা: বেছে নেওয়া QualityHint প্রয়োগ করে অ্যাক্টিভ লাইভ স্ট্রিমের স্ট্রিমিং রেজোলিউশন পরিবর্তন করুন (যেমন, স্ট্যান্ডার্ড ডেফিনিশন থেকে হাই ডেফিনিশনে পরিবর্তন করা)। changeQuality ফাংশন ডিভাইসের লাইভ স্ট্রিমিং সংক্রান্ত বৈশিষ্ট্য সমাধান করে এবং অ্যাক্টিভ mediaSessionId ও বেছে নেওয়া QualityHint কনফিগারেশনের সাথে changeLiveViewQuality কল করে।

// Assuming you have a HomeDevice instance 'device'
val availableQualityHints: StateFlow<List> =
    device.type(GoogleDoorbellDevice)
        .trait(WebRtcLiveView)
        .map { trait -> 
            trait?.supportedQualityHints ?: emptyList() 
        }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())

// Assuming you have a HomeDevice instance 'device'
suspend fun changeQuality(mediaSessionId: String, qualityHint: QualityHint) {
    // Get the trait from the device
    val trait = device.type(GoogleDoorbellDevice).trait(WebRtcLiveView).first() ?: return
    try {
        trait.changeLiveViewQuality(mediaSessionId, qualityHint)
    } catch (e: Exception) {
        // Handle error
    }
}

ব্যাটারি সেটিংস

Home API-এর মাধ্যমে বিভিন্ন ব্যাটারি সেটিংস কন্ট্রোল করা যায়।

ব্যাটারি ব্যবহার সংক্রান্ত পছন্দ সেট করা

এনার্জি ব্যালেন্স সেট করলে, ডিভাইসের ব্যাটারি লাইফ ও পারফর্ম্যান্সের মধ্যে ট্রেড-অফ কনফিগার করতে পারবেন। আপনি আলাদা আলাদা ব্যাটারি প্রোফাইল তৈরি করতে পারবেন, যেমন, "এক্সটেন্ডেড", "ব্যালেন্সড" ও "পারফর্ম্যান্স" এবং এগুলির মধ্যে পরিবর্তন করতে পারবেন।

এই ফিচারটি currentEnergyBalance অ্যাট্রিবিউট আপডেট করে EnergyPreference ট্রেড প্রয়োগ করে। অ্যাট্রিবিউটটি একটি পূর্ণসংখ্যা ইনডেক্স গ্রহণ করে যা ডিভাইসের energyBalances তালিকায় (যেমন, EXTENDED-এর জন্য 0, BALANCED-এর জন্য 1 এবং PERFORMANCE-এর জন্য 2) সংজ্ঞায়িত নির্দিষ্ট প্রোফাইলের সাথে সম্পর্কিত।

currentEnergyBalance-এর জন্য null ভ্যালু থেকে বোঝা যায় যে ডিভাইসটি কাস্টম প্রোফাইল ব্যবহার করছে। এটি হল শুধু পড়া যায় এমন অবস্থা।

নিচে এমন একটি স্ট্রাকচারের উদাহরণ দেখানো হয়েছে যা currentEnergyBalance অ্যাট্রিবিউট ব্যবহার করবে, এর পরে অ্যাট্রিবিউট ব্যবহার করা আসল কোড স্নিপেট দেখানো হয়েছে।

// Example energyBalances list
energy_balances: [
  {
    step: 0,
    label: "EXTENDED"
  },
  {
    step: 50,
    label: "BALANCED"
  },
  {
    step: 100,
    label: "PERFORMANCE"
  }
]
// The index parameter must be within the UByte range (0-255).
suspend fun setEnergyBalance(trait: EnergyPreference, index: Int) {
  trait.update { setCurrentEnergyBalance(index.toUByte()) }
}

// Setting the battery usage to more recording ie performance
setEnergyBalance(energyPreference, 2)

অটোমেটিক ব্যাটারি সেভার চালু করা

এই ফিচার কনফিগার করতে, এই currentLowPowerModeSensitivity অ্যাট্রিবিউটটি EnergyPreference ট্রেটের মধ্যে আপডেট করুন। এই অ্যাট্রিবিউট সংবেদনশীলতার লেভেল বেছে নিতে একটি ইন্ডেক্স ব্যবহার করে, যেখানে 0 সাধারণত Disabled এবং 1 Enabled অথবা Automatic-কে বোঝায়।

suspend fun setAutomaticBatterySaver(enable: Boolean, trait: EnergyPreference) {
  // 0 is Disabled, 1 is Enabled
  val value = if (enable) 1.toUByte() else 0.toUByte()
  trait.update { setCurrentLowPowerModeSensitivity(value) }
}

ব্যাটারি চার্জিংয়ের অবস্থা পাওয়া

ডিভাইসের বর্তমান চার্জিং স্ট্যাটাস (চার্জ হচ্ছে, সম্পূর্ণ চার্জ হয়ে গেছে বা চার্জ হচ্ছে না) পেতে, batChargeState অ্যাট্রিবিউট ব্যবহার করুন। এটি PowerSource ট্রেটের মধ্যে থাকে।

// Get the battery charging state
val batteryChargeState = powerSource.batChargeState

when (batteryChargeState) {
    PowerSourceTrait.BatChargeStateEnum.IsCharging -> "Charging"
    PowerSourceTrait.BatChargeStateEnum.IsAtFullCharge -> "Full"
    PowerSourceTrait.BatChargeStateEnum.IsNotCharging -> "Not Charging"
    else -> "Unknown"
}

ব্যাটারি লেভেল পাওয়া

বর্তমান ব্যাটারি লেভেল পেতে, PowerSource ট্রেটের batChargeLevel অ্যাট্রিবিউট ব্যবহার করুন। লেভেল OK, Warning (কম) অথবা Critical।

// Get the battery charge level
val batteryLevel = powerSourceTrait.batChargeLevel

when (batteryLevel) {
    PowerSourceTrait.BatChargeLevelEnum.OK -> "OK"
    PowerSourceTrait.BatChargeLevelEnum.Warning -> "Warning"
    PowerSourceTrait.BatChargeLevelEnum.Critical -> "Critical"
    else -> "Unknown"
}

পাওয়ার সোর্স পাওয়া

ডিভাইস কোন পাওয়ার সোর্স ব্যবহার করছে তা নির্ধারণ করতে, PowerSource ট্রেটের BatPresent ও wiredPresent অ্যাট্রিবিউট ব্যবহার করুন।

  val trait: PowerSource
  val isWired = trait.wiredPresent
  val hasBattery = trait.batPresent

ব্যাটারি পাল্টাতে হবে কিনা তা চেক করুন

batReplaceability অ্যাট্রিবিউট থেকে বোঝা যায় যে ব্যাটারি পরিবর্তন করা যায় না, ব্যবহারকারী পরিবর্তন করতে পারেন অথবা ফ্যাক্টরিতে পরিবর্তন করতে হয়।

PowerSource ট্রেটের batReplacementNeeded অ্যাট্রিবিউট থেকে আপনি জানতে পারবেন যে ব্যাটারি পরিবর্তন করতে হবে কিনা।

// Get the battery replacement status
val batteryStatus = powerSourceTrait.batReplacementNeeded

if (batteryStatus) {
  println("Replace the battery.")
}

ব্যাটারি ব্যবহারকারী-পরিবর্তনযোগ্য হলে, সেটি batReplacementDescription ব্যাটারির বিবরণ দেয়, যার মধ্যে ফর্ম ফ্যাক্টর, কেমিস্ট্রি এবং পছন্দের প্রস্তুতকারকের মতো তথ্য অন্তর্ভুক্ত থাকে।

অডিও সেটিংস

Home API-এর মাধ্যমে বিভিন্ন অডিও সেটিংস কন্ট্রোল করা যায়।

মাইক্রোফোন চালু বা বন্ধ করা

ডিভাইসের মাইক্রোফোন চালু বা বন্ধ করতে, বিল্ট-ইন setMicrophoneMuted Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement ট্রেটের microphoneMuted অ্যাট্রিবিউট আপডেট করুন:

// Turn the device's microphone on or off
suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setMicrophoneMuted(disableMicrophone) }
}

অডিও রেকর্ডিং চালু বা বন্ধ করা

ডিভাইসের জন্য অডিও রেকর্ডিং চালু বা বন্ধ করতে, বিল্ট-ইন setRecordingMicrophoneMuted Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement ট্রেটের recordingMicrophoneMuted অ্যাট্রিবিউট আপডেট করুন:

// Turn audio recording on or off for the device
suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setRecordingMicrophoneMuted(disableAudioRecording) }
}

স্পিকারের ভলিউম অ্যাডজাস্ট করা

ডিভাইসের স্পিকার ভলিউম অ্যাডজাস্ট করতে, বিল্ট-ইন setSpeakerVolumeLevel Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement ট্রেটের speakerVolumeLevel অ্যাট্রিবিউট আপডেট করুন:

// Adjust the camera speaker volume
suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) {
  trait.update { setSpeakerVolumeLevel(volume.toUbyte()) }
}

অ্যাক্টিভিটি জোন সেটিংস

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

ZoneManagement ট্রেট ক্যামেরা ও ডোরবেল ডিভাইসে কাস্টম আগ্রহের অঞ্চল (অ্যাক্টিভিটি জোন) ম্যানেজ করার জন্য ইন্টারফেস প্রদান করে। ডিভাইসের ফিল্ড অফ ভিউয়ের মধ্যে নির্দিষ্ট এলাকায় ইভেন্ট শনাক্তকরণ (যেমন, ব্যক্তি বা গাড়ির গতিবিধি) ফিল্টার করতে এইসব জোন ব্যবহার করা হয়।

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

অ্যাক্টিভিটি জোন সাধারণত 2D কার্টেসিয়ান কোঅর্ডিনেট ব্যবহার করে নির্ধারণ করা হয়। এই ট্রেট ভার্টেক্সের জন্য TwoDCartesianVertexStruct এবং জোন ডেফিনিশনের জন্য TwoDCartesianZoneStruct (নাম, ভার্টেক্স, রঙ ও ব্যবহার) প্রদান করে।

অ্যাক্টিভিটি জোন চেক করা

অ্যাক্টিভিটি জোন দেখাতে, ZoneManagement ট্রেটের zones অ্যাট্রিবিউট চেক করুন।

// 1. Obtain the trait flow from the device
private val zoneManagementFlow: Flow =
  device.type(CAMERA_TYPE).flatMapLatest { it.trait(ZoneManagement) }

// 2. Map the flow to the list of zone structures
val activityZones: Flow<List<ZoneManagementTrait.ZoneInformationStruct>> =
  zoneManagementFlow.map { trait ->
    trait.zones ?: emptyList()
  }

অ্যাক্টিভিটি জোন যোগ করা

নতুন জোন তৈরি করতে, createTwoDCartesianZone কমান্ড ব্যবহার করুন। এই কমান্ড একটি TwoDCartesianZoneStruct নেয়, যা জোনের নাম, ভার্টেক্স, রঙ ও ব্যবহারকে সংজ্ঞায়িত করে।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে যে কীভাবে চারটি শীর্ষবিন্দু সহ "ফ্রন্ট পোর্চ" নামের একটি জোন তৈরি করতে হয়, যার রঙ হল স্যামন (#F439A0) এবং যা মোশন শনাক্তকরণের জন্য ব্যবহার করা হয়।

import com.google.home.google.ZoneManagement
import com.google.home.google.ZoneManagementTrait
import com.google.home.matter.serialization.OptionalValue

/**
 * Creates a custom activity zone named "Front Porch" with a salmon color
 * configured for motion detection.
 */
suspend fun createFrontPorchZone(zoneManagement: ZoneManagement) {
  // 1. Define the vertices for the zone (2D Cartesian coordinates)
  // Values are typically scaled to a maximum defined by the device's twoDCartesianMax attribute.
  val vertices =
    listOf(
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260u, y = 422u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049u, y = 0u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 0u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 950u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630u, y = 1349u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880u, y = 2048u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0u, y = 2048u),
      ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638u, y = 1090u)
    )

  // 2. Define the zone structure
  val newZone =
    ZoneManagementTrait.TwoDCartesianZoneStruct(
      name = "Front Porch",
      vertices = vertices,
      // Usage defines what the zone filters (for example, Motion, Person, Vehicle)
      use = listOf(ZoneManagementTrait.ZoneUseEnum.Motion),
      // Color is typically a hex string (for example, Salmon/Pink)
      color = OptionalValue.present("#F439A0")
    )

  try {
    // 3. Execute the command to add the zone to the device
    zoneManagement.createTwoDCartesianZone(newZone)
    println("Successfully created activity zone.")
  } catch (e: Exception) {
    // Handle potential HomeException or Timeout
    println("Failed to create activity zone: ${e.message}")
  }
}

অ্যাক্টিভিটি জোন আপডেট করা

আগে থেকে থাকা কোনও জোন আপডেট করতে, updateTwoDCartesianZone কমান্ড ব্যবহার করুন। এই কমান্ডের জন্য zoneId ও আপডেট করা TwoDCartesianZoneStruct প্রয়োজন।

private suspend fun ZoneManagement.updateZone(
  zoneId: UShort,
  zone: ZoneManagementTrait.TwoDCartesianZoneStruct
) {
  // Execute the command to update the zone
  this.updateTwoDCartesianZone(zoneId = zoneId, zone = zone)
}

অ্যাক্টিভিটি জোন মুছে দেওয়া

কোনও জোন সরাতে, নির্দিষ্ট zoneId সহ removeZone কমান্ড ব্যবহার করুন।

private suspend fun ZoneManagement.deleteZone(zoneId: UShort) {
  // Execute the command to remove the zone
  this.removeZone(zoneId = zoneId)
}

সাউন্ড ইভেন্ট ট্রিগার

AvStreamAnalysis ট্রেট ক্যামেরা ও ডোরবেল ডিভাইসে ইভেন্ট শনাক্তকরণ ট্রিগার ম্যানেজ করার জন্য ইন্টারফেস প্রদান করে। ভিজ্যুয়াল-ভিত্তিক ট্রিগার (যেমন, মানুষ বা যানবাহন) জোন-নির্দিষ্ট হতে পারে, তবে সাউন্ড-সম্পর্কিত ট্রিগার সাধারণত ডিভাইস-লেভেল কনফিগারেশন হয়।

EventTriggerTypeEnum-এর মাধ্যমে সাউন্ড শনাক্তকরণের জন্য নিম্নলিখিত ট্রিগার উপলভ্য:

মোড Enum ভ্যালু বিবরণ
সাউন্ড Sound সাধারণ সাউন্ড শনাক্তকরণ।
কেউ কথা বলছে PersonTalking স্পিচ শনাক্ত করে।
কুকুরের ডাক DogBark কুকুরের ডাক শনাক্ত করে।
গ্লাস ব্রেক GlassBreak কাঁচ ভাঙার শব্দ শনাক্ত করে।
স্মোক অ্যালার্ম SmokeAlarm ধোঁয়ার অ্যালার্ম শনাক্ত করে, যা প্রায়ই T3 অডিবল প্যাটার্ন (তিনটি ছোট বিপিংয়ের পরে একটি পজ) দ্বারা শনাক্ত করা হয়।
CO অ্যালার্ম CoAlarm কার্বন মনোক্সাইড (CO) অ্যালার্ম শনাক্ত করে, যা সাধারণত T4 শ্রুতিগম্য প্যাটার্ন (চারটি ছোট বিপিংয়ের পরে একটি পজ) দ্বারা শনাক্ত করা হয়।

সাউন্ড শনাক্তকরণের স্ট্যাটাস চেক করা

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

Kotlin Flows ব্যবহার করে Android ডেভেলপমেন্টে, আপনি সাধারণত HomeDevice থেকে AvStreamAnalysis ট্রেট পর্যবেক্ষণ করবেন।

// Example structure to store the
data class EventTriggerAttribute(val type: EventTriggerTypeEnum, val enabled: Boolean)

// 1. Obtain the trait flow from the device
private val avStreamAnalysisFlow: Flow<AvStreamAnalysis> =
  device.traitFromType(AvStreamAnalysis, CAMERA_TYPES.first { device.has(it) })

// 2. Map the flow to a list of sound event attributes
val soundEventTriggersState: Flow<List<EventTriggerAttribute>> =
  avStreamAnalysisFlow.map { trait ->
    // Get raw lists from the trait attributes
    val supported = trait.supportedEventTriggers ?: emptyList()
    val enabled = trait.enabledEventTriggers ?: emptyList()

    // Define sound-specific triggers to filter for
    val soundTypes = setOf(
      EventTriggerTypeEnum.Sound,
      EventTriggerTypeEnum.PersonTalking,
      EventTriggerTypeEnum.DogBark,
      EventTriggerTypeEnum.GlassBreak,
      EventTriggerTypeEnum.SmokeAlarm,
      EventTriggerTypeEnum.CoAlarm,
    )

    // Filter and associate status
    supported
      .filter { soundTypes.contains(it) }
      .map { type ->
        EventTriggerAttribute(
          type = type,
          enabled = enabled.contains(type)
        )
      }
  }

চালু করা ট্রিগারের সেট আপডেট করা

চালু করা ট্রিগারের সেট আপডেট করতে, SetOrUpdateEventDetectionTriggers কমান্ড ব্যবহার করুন, যা EventTriggerEnablement স্ট্রাকচারের একটি তালিকা নেয়।

private suspend fun AvStreamAnalysis.updateEventTriggers(
  eventTriggers: List<EventTriggerAttribute>
) {
  val toUpdate = eventTriggers.map {
    EventTriggerEnablement(
      eventTriggerType = it.type,
      enablementStatus = if (it.enabled) {
        EnablementStatusEnum.Enabled
      } else {
        EnablementStatusEnum.Disabled
      },
    )
  }

  // Execute the command on the device
  setOrUpdateEventDetectionTriggers(toUpdate)
}

রেকর্ডিং মোড

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

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

RecordingModeEnum উপলভ্য রেকর্ডিং স্ট্র্যাটেজি নির্ধারণ করে:

মোড Enum ভ্যালু বিবরণ
বন্ধ করা হয়েছে Disabled রেকর্ডিং সম্পূর্ণভাবে বন্ধ করা আছে। প্রধানত পুরনো ডিভাইস ব্যবহার করে।
CVR (অবিচ্ছিন্ন ভিডিও রেকর্ডিং) Cvr ভিডিও ২৪x৭ রেকর্ড করা হয়। সাবস্ক্রিপশন থাকতে হবে (যেমন, Google Home Premium.
EBR (ইভেন্ট ভিত্তিক রেকর্ডিং) Ebr ইভেন্ট (ব্যক্তি, মোশন) দ্বারা রেকর্ডিং ট্রিগার করা হয়। ভিডিওর দৈর্ঘ্য ইভেন্টের সময়সীমা ও সাবস্ক্রিপশনের উপর নির্ভর করে।
ETR (ইভেন্ট ট্রিগার করা রেকর্ডিং) Etr ইভেন্ট দ্বারা ট্রিগার করা সংক্ষিপ্ত প্রিভিউ রেকর্ডিং (যেমন, ১০ সেকেন্ড)।
Live View LiveView রেকর্ডিং বন্ধ করা আছে, কিন্তু ব্যবহারকারীরা এখনও লাইভ স্ট্রিম অ্যাক্সেস করতে পারবেন।
স্থির ছবি Images ইভেন্ট ঘটলে ভিডিওর পরিবর্তে স্ন্যাপশট রেকর্ড করা হয়।

রেকর্ডিং মোড চেক করা

বর্তমান রেকর্ডিং কনফিগারেশন দেখতে, RecordingMode ট্রেটের অ্যাট্রিবিউট চেক করুন:

// 1. Obtain the trait flow from the device
private val recordingModeTraitFlow: Flow =
    device.traitFromType(RecordingMode, CAMERA_TYPES.first { device.has(it) })

// 2. Map the flow to recording mode options
data class RecordingModeOptions(
    val recordingMode: RecordingModeTrait.RecordingModeEnum,
    val index: Int,
    val available: Boolean,
    val readableString: String,
)

private val recordingModeOptions: Flow<List> =
    recordingModeTraitFlow.map { trait ->
        val supported = trait.supportedRecordingModes?.map { it.recordingMode } ?: emptyList()
        val available = trait.availableRecordingModes?.map { it.toInt() } ?: emptyList()

        supported.withIndex().map { (index, mode) ->
            RecordingModeOptions(
                recordingMode = mode,
                index = index,
                available = available.contains(index),
                readableString = mode.toReadableString(),
            )
        }
    }

রেকর্ডিং মোড পরিবর্তন করা

আপডেট করার আগে, নিশ্চিত করুন যে availableRecordingModes অ্যাট্রিবিউটে supportedRecordingModes অ্যাট্রিবিউট থেকে বেছে নেওয়া ইন্ডেক্স আছে।

বেছে নেওয়া মোড আপডেট করতে, বেছে নেওয়া মোডের ইন্ডেক্স পাস করে setSelectedRecordingMode ফাংশন ব্যবহার করুন:

private suspend fun RecordingMode.updateRecordingMode(index: Int) {
    // Execute the command to update the selected mode
    this.setSelectedRecordingMode(index.toUByte())
}

অন্যান্য সেটিংস

Home API-এর মাধ্যমে আরও বিভিন্ন সেটিংস কন্ট্রোল করা যায়।

নাইট ভিশন চালু বা বন্ধ করা

ক্যামেরার জন্য নাইট ভিশন চালু বা বন্ধ করতে, বিল্ট-ইন setNightVision Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement ট্রেডের nightVision অ্যাট্রিবিউট আপডেট করতে TriStateAutoEnum ব্যবহার করুন:

// Turn night vision on
cameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On)
}

// Turn night vision off
CameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off)
}

স্ট্যাটাস LED-এর উজ্জ্বলতা পরিবর্তন করা

স্ট্যাটাস LED-এর উজ্জ্বলতা পরিবর্তন করতে, বিল্ট-ইন setStatusLightBrightness Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement ট্রেটের statusLightBrightness অ্যাট্রিবিউট আপডেট করতে ThreeLevelAutoEnum ব্যবহার করুন:

// Set the LED brightness to high
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High)
}

// Set the LED brightness to low
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low)
}

ক্যামেরা ভিউপোর্ট পরিবর্তন করা

ক্যামেরা ভিউপোর্ট হল সেই একই ফিচার যা Nest ক্যামেরার ভিডিও জুম ও এনহ্যান্স করা সংক্রান্ত সহায়তা নিবন্ধে জুম ও ক্রপ ফিচার হিসেবে বর্ণনা করা হয়েছে।

ViewportStruct-এ ভিউপোর্টকে সংজ্ঞায়িত করা হয়, এতে চারটি মান থাকে, যা ভিউপোর্টের কোঅর্ডিনেট হিসেবে ব্যবহার করা হয়। কোঅর্ডিনেটকে এইভাবে সংজ্ঞায়িত করা হয়:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

ViewportStruct-এর ভ্যালু নির্ধারণ করা অ্যাপের UI এবং ক্যামেরা প্রয়োগের উপর নির্ভর করে। খুবই প্রাথমিক লেভেলে, ক্যামেরা ভিডিওর ভিউপোর্ট সেট করতে, CameraAvStreamManagement ট্রেটের viewport অ্যাট্রিবিউটকে ViewportStruct দিয়ে আপডেট করুন, এর জন্য বিল্ট-ইন setViewport Kotlin ফাংশন ব্যবহার করুন:

cameraAvStreamManagement
  .update { setViewport(
    CameraAvStreamManagementTrait.ViewportStruct(
      x1 = horizontalRange.rangeStart.roundToInt().toUShort(),
      x2 = horizontalRange.rangeEnd.roundToInt().toUShort(),
      y1 = verticalRange.rangeStart.roundToInt().toUShort(),
      y2 = verticalRange.rangeEnd.roundToInt().toUShort(),
    )
) }

অ্যানালিটিক্স চালু বা বন্ধ করা

প্রতিটি ডিভাইস আলাদাভাবে Google Home ক্লাউডে (হোমের জন্য ক্লাউড মনিটরিং API দেখুন) বিস্তারিত অ্যানালিটিক্স ডেটা পাঠানোর জন্য অপ্ট-ইন করতে পারে।

কোনও ডিভাইসের জন্য অ্যানালিটিক্স চালু করতে, ExtendedGeneralDiagnosticsTrait প্রপার্টির analyticsEnabled মান true হিসেবে সেট করুন। আপনি analyticsEnabled সেট করলে, অন্য একটি প্রপার্টি logUploadEnabled অটোমেটিক true হিসেবে সেট হয়ে যায়, যা Google Home ক্লাউডে অ্যানালিটিক্স লগ ফাইল আপলোড করার অনুমতি দেয়।

// Enable analytics
extendedGeneralDiagnostics.update {
  setAnalyticsEnabled(true)
}

// Disable analytics
extendedGeneralDiagnostics.update {
  setAnalyticsEnabled(false)
}

ট্রান্সপোর্ট ও রেকর্ডিং কনফিগারেশন

এই বিভাগে ক্যামেরা স্ট্রিমিং কোয়ালিটি ও ইভেন্ট ট্রিগার করা সম্পর্কিত সেটিংস অন্তর্ভুক্ত। এইসব সেটিংস PushAvStreamTransport ট্রেইট ম্যানেজ করে।

ট্রান্সপোর্ট সেটিংস পড়া

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

val trait: PushAvStreamTransport = device.getTrait(PushAvStreamTransport)
val connections = trait.findTransport().transportConfigurations

// Locate the connection designated for recording
val recordingConnection = connections.firstOrNull {
    it.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording
}

val options = recordingConnection?.transportOptions?.getOrNull()

// 1. Bandwidth Quality (Video Stream ID)
val videoStreamId = options?.videoStreamId?.getOrNull()

// 2. Wake-up Sensitivity (Motion Sensitivity)
val wakeUpSensitivity = options?.triggerOptions?.motionSensitivity?.getOrNull()

// 3. Max Event Length (Motion Trigger Time Control)
val maxEventLength = options?.triggerOptions?.motionTimeControl?.getOrNull()?.maxDuration

পরিবহন সংক্রান্ত সেটিংস আপডেট করা

এই বিভাগে কীভাবে ট্রান্সপোর্ট সেটিংস পরিবর্তন করতে হয় তা দেখানো হয়েছে। এটি নতুন ভ্যালু সহ একটি নতুন TransportOptionsStruct তৈরি করে এবং তারপরে modifyPushTransport কমান্ড ব্যবহার করে এই আপডেট করা সেটিংস ডিভাইসে ফেরত পাঠায় এবং আগের ধাপে পাওয়া রেকর্ডিং কানেকশনে সেগুলি প্রয়োগ করে।

এইসব সেটিংস পরিবর্তন করতে, TransportOptionsStruct সহ modifyPushTransport কমান্ড ব্যবহার করুন।

val toUpdate = TransportOptionsStruct(
    videoStreamId = OptionalValue.present(2u), // e.g., Max Quality
    triggerOptions = TransportTriggerOptionsStruct(
        motionSensitivity = OptionalValue.present(5u), // e.g., Medium
        motionTimeControl = OptionalValue.present(
            TransportMotionTriggerTimeControlStruct(maxDuration = 30u)
        )
    )
)

if (recordingConnection != null) {
    trait.modifyPushTransport(
        connectionId = recordingConnection.connectionId,
        transportOptions = toUpdate
    )
}

ব্যান্ডউইথের কোয়ালিটি নির্ধারণ করা

videoStreamId TransportOptionsStruct-এর প্রপার্টি একটি নির্দিষ্ট ভিডিও স্ট্রিম কনফিগারেশনের সাথে সম্পর্কিত।

সাপোর্ট করা ভিডিও স্ট্রিম পেতে, allocatedVideoStreams অ্যাট্রিবিউট দেখুন, যেটি VideoStreamStructs-এর তালিকা। ডিভাইসের CameraAvStreamManagement trait থেকে।

ডিভাইস ওয়েক-আপ সেন্সিটিভিটি অ্যাডজাস্ট করা

TransportTriggerOptionsStruct-এর motionSensitivity প্রপার্টি নিম্নলিখিত ভ্যালুর সাথে সম্পর্কিত:

লেবেল মান (UByte)
কম 1u
মাঝারি 5u
বেশি 10u

ইভেন্টের সর্বাধিক দৈর্ঘ্য অ্যাডজাস্ট করা

maxDuration প্রপার্টির TransportMotionTriggerTimeControlStruct সাথে নিম্নলিখিত সময়সীমা (সেকেন্ডে) সম্পর্কিত:

  • 10u, 15u, 30u, 60u, 120u, 180u

চাইম সেটিংস

Home API-এর মাধ্যমে ডোরবেল চিমের বিভিন্ন সেটিংস কন্ট্রোল করা যায়।

চাইমের সাউন্ড পরিবর্তন করা

ডোরবেল চিমের সাউন্ড পরিবর্তন করতে, প্রথমে ডিভাইসে ইনস্টল করা চিমের সাউন্ডের তালিকা পান, এর জন্য Chime ট্রেটের installedChimeSounds অ্যাট্রিবিউট ব্যবহার করুন:

// Get a list of chimes and identify the currently selected one
private val doorbellChimeTraitFlow: Flow =
    device.traitFromType(Chime, GoogleDoorbellDevice)
val chimeSounds = doorbellChimeTraitFlow.first().installedChimeSounds ?: emptyList()

তারপর, বিল্ট-ইন setSelectedChime Kotlin ফাংশন ব্যবহার করে Chime ট্রেটের selectedChime অ্যাট্রিবিউট আপডেট করুন:

// Set the chime using the chimeId from the installed list
chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }

এক্সটার্নাল চিম ব্যবহার করা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

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

কোন ধরনের এক্সটার্নাল চিম ইনস্টল করা আছে তা বোঝাতে, বিল্ট-ইন setExternalChime Kotlin ফাংশন ব্যবহার করে Chime ট্রেটের externalChime অ্যাট্রিবিউট আপডেট করতে ExternalChimeType ব্যবহার করুন:

// Indicate the external chime is mechanical
chime.update {
  setExternalChime(ChimeTrait.ExternalChimeType.Mechanical)
}

এক্সটার্নাল চাইম বাজার সময়সীমা পরিবর্তন করা

এক্সটার্নাল চিম কতক্ষণ বাজবে তা সেকেন্ডে হিসেব করা হয় এবং Home API-এর মাধ্যমে তা কনফিগার করা যায়। এক্সটার্নাল চিম যদি চিম বেজে ওঠার সময়সীমা কাজ করে, তাহলে ব্যবহারকারী এটি কনফিগার করতে চান।

এখানে সেট করা ভ্যালু এক্সটার্নাল চাইমের স্পেসিফিকেশন এবং এর সাজেস্ট করা চাইম বাজার সময়সীমার উপর নির্ভর করে।

এক্সটার্নাল চিমের সময়সীমা পরিবর্তন করতে, বিল্ট-ইন setExternalChimeDurationSeconds Kotlin ফাংশন ব্যবহার করে Chime ট্রেটের externalChimeDurationSeconds অ্যাট্রিবিউট আপডেট করুন:

// Change the external chime duration
chime.update {
  setExternalChimeDurationSeconds(newDuration.toUShort())
}

চিম থিম চালু করা

   Android-এর জন্য Sample App-এ প্রয়োগ করা হয়েছে   

কিছু ডোরবেলে এমন চিম থাকতে পারে যা ব্যবহারকারীদের জন্য সীমিত সময়ের জন্য উপলভ্য। যেমন, ছুটির দিনের জন্য নির্দিষ্ট চিম। এগুলিকে চিম থিম বলা হয়।

কোনও ব্যবহারকারীর জন্য কোন চিম থিম উপলভ্য তা দেখতে, টাইমবক্স ফিল্টার তৈরি করুন এবং ChimeThemes ট্রেড থেকে getAvailableThemes() কমান্ডের ফলাফল ফিল্টার করতে এটি ব্যবহার করুন। এটি থিমের নাম সহ উপলভ্য থিমের একটি তালিকা রিটার্ন করে।

নিচের উদাহরণ থেকে কীভাবে তালিকা ফিল্টার করতে হয় তা জানুন। কোনও থিমের বর্তমান সময় তার শুরু ও শেষের সময়ের মধ্যে থাকলে (যথাক্রমে startTimeSeconds ও endTimeSeconds ভ্যালু), সেটিকে অ্যাক্টিভ হিসেবে বিবেচনা করা হয়। শুরু হওয়ার সময় সেট করা না থাকলে, এটি শুরু থেকে অ্যাক্টিভ হিসেবে বিবেচনা করা হয়। শেষ হওয়ার সময় সেট করা না থাকলে, এটি অনির্দিষ্টকালের জন্য চালু থাকে। দুটিই না থাকলে, থিম সবসময় চালু থাকে।

// Get themes from the ChimeThemes trait
fun List<ChimeThemesTrait.ThemeStruct>.filterTimeboxedThemes():
    List<ChimeThemesTrait.ThemeStruct> {
  val now = timeSource.instant().epochSecond.toULong()
  return filter { chimeStruct: ChimeThemesTrait.ThemeStruct ->
    val startTime: ULong = chimeStruct.startTimeSeconds.getOrNull() ?: 0UL
    val endTime: ULong = chimeStruct.endTimeSeconds.getOrNull() ?: MAX_VALUE
    startTime <= now && now <= endTime
  }
}

val availableThemes =
  doorbellChimeThemesTraitFlow
    .first()
    .getAvailableThemes()
    .themes
    .filterTimeboxedThemes()

আপনি যে থিম চান তার নাম, যেমন Christmas, পেয়ে গেলে, আপনি ChimeThemes ট্রেইটে গিয়ে setSelectedTimeboxedThemeName() ফাংশন ব্যবহার করে সেটি বেছে নিতে পারবেন:

// Select a theme using the ChimeThemes trait
val themeToSelect = "Christmas"
if (themeToSelect in availableThemeNames) {
  doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect)
}

ভিজিটর ঘোষণা সংক্রান্ত সেটিংস

আপনি Home API's VisitorAnnouncement ট্রেড ব্যবহার করে ডোরবেলের জন্য ভিজিটর ঘোষণা সেটিংস কোয়েরি ও ম্যানেজ করতে পারবেন। এই ট্রেট নিয়ন্ত্রণ করে যে কেউ কলিং বেল বাজালে Google স্মার্ট স্পিকার বা ডিসপ্লেতে কোনও ভিজিটর এসেছেন কিনা তা ঘোষণা করা হবে কিনা।

নিচের উদাহরণ থেকে কীভাবে ভিজিটর অ্যানাউন্সমেন্ট চালু আছে কিনা তা চেক করতে হয় এবং কীভাবে এই সেটিং আপডেট করতে হয় তা জানুন:

// Read the current visitor announcements state
val isEnabled = visitorAnnouncementTrait.visitorAnnouncementsEnabled

// Toggle the visitor announcements setting
visitorAnnouncementTrait.update {
    setVisitorAnnouncementsEnabled(true)
}

ডিভাইস বন্ধ করা

স্ট্রাকচার থেকে ডোরবেল সরাতে, কল করুন device.decommissionDevice()। ডিকমিশন করার সময় ব্যবহারকারীকে Google-ম্যানেজ করা কনফার্মেশন স্ক্রিন দেখানো হয়, যেখানে ২৪/৭ রেকর্ড করা ভিডিওর ইতিহাস, ইভেন্টের ইতিহাস, ক্লিপ ও পরিচিত মুখ লাইব্রেরির ডেটা স্ট্রাকচার জুড়ে স্থায়ীভাবে মুছে যাওয়ার কথা বলা হয়।

বিস্তারিত নির্দেশাবলী ও কোডের উদাহরণ পেতে, ডিভাইস সরিয়ে দিন দেখুন।