অ্যান্ড্রয়েডের জন্য ক্যামেরা ডিভাইস গাইড

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

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

হোম এপিআই ডিভাইসের ধরন বৈশিষ্ট্য কোটলিন নমুনা অ্যাপ ব্যবহারের ক্ষেত্র

ক্যামেরা

Google Camera Device

home.matter.6006.types.0158

একটি ডিভাইস যা স্থির চিত্র বা ভিডিও ধারণ করে। ক্যামেরাগুলিতে অ্যাক্সেসযোগ্য লাইভস্ট্রিম, দ্বিমুখী টকব্যাক বা ডিটেকশন ইভেন্টের মতো বৈশিষ্ট্য থাকতে পারে।

প্রয়োজনীয় বৈশিষ্ট্য
গুগল পুশএভিস্ট্রিমট্রান্সপোর্ট
গুগল ওয়েবআরটিসিলাইভভিউ

ক্যামেরা

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

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}")
        println("serialNumber ${basicInformation.serialNumber}")
    }

ডিভাইস ক্লাউড যোগাযোগের সর্বশেষ সময় পান

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

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

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

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

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

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

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

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

  • অধিবেশনের জন্য এসডিপি।
  • সেশনের সময়কাল সেকেন্ডে।
  • সেশন আইডি, যা সেশনটির মেয়াদ বাড়াতে বা শেষ করতে ব্যবহার করা যেতে পারে।
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) {
 return cameraDevice.type(GoogleCameraDevice).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)

একটি লাইভস্ট্রিম প্রসারিত করুন

লাইভস্ট্রিমের একটি পূর্বনির্ধারিত সময়কাল থাকে, যার পরে তা শেষ হয়ে যায়। একটি সক্রিয় স্ট্রিমের সময়কাল বাড়ানোর জন্য, 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
}

টকব্যাক শুরু এবং বন্ধ করুন

টকব্যাক শুরু করতে, 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)
  }
}

রেকর্ডিং ক্ষমতা চালু এবং বন্ধ করুন

ক্যামেরার রেকর্ডিং ক্ষমতা চালু করতে, PushAvStreamTransport ট্রেইটের setTransportStatus() মেথডে TransportStatusEnum.Active পাস করুন। রেকর্ডিং ক্ষমতা বন্ধ করতে, এতে 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)
  }
}

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

যখন রেকর্ডিং ক্ষমতা নিষ্ক্রিয় থাকে (ক্যামেরার ভিডিও বন্ধ থাকে):

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

রেকর্ডিং ক্ষমতা সক্রিয় আছে কিনা তা পরীক্ষা করুন।

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

// 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
    }
}

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

হোম এপিআই-এর মাধ্যমে ব্যাটারির বিভিন্ন সেটিংস নিয়ন্ত্রণ করা যায়।

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

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

এই ফিচারটি EnergyPreference ট্রেইটের currentEnergyBalance অ্যাট্রিবিউট আপডেট করার মাধ্যমে প্রয়োগ করা হয়। অ্যাট্রিবিউটটি একটি পূর্ণসংখ্যা ইনডেক্স গ্রহণ করে, যা ডিভাইসের 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)

স্বয়ংক্রিয় ব্যাটারি সেভার চালু করুন

এই ফিচারটি কনফিগার করতে, EnergyPreference ট্রেইটের currentLowPowerModeSensitivity অ্যাট্রিবিউটটি আপডেট করুন। এই অ্যাট্রিবিউটটি একটি সেনসিটিভিটি লেভেল নির্বাচন করার জন্য একটি ইনডেক্স ব্যবহার করে, যেখানে 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) }
}

ব্যাটারি চার্জিং অবস্থা জানুন

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

// 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

অডিও সেটিংস

হোম এপিআই-এর মাধ্যমে বিভিন্ন অডিও সেটিংস নিয়ন্ত্রণ করা যায়।

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

ডিভাইসের মাইক্রোফোন চালু বা বন্ধ করতে, বিল্ট-ইন 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()) }
}

কার্যকলাপ অঞ্চলের সেটিংস

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)
}

রেকর্ডিং মোড

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

RecordingModeEnum উপলব্ধ রেকর্ডিং কৌশলগুলি নির্ধারণ করে:

মোড Enum মান বর্ণনা
প্রতিবন্ধী Disabled রেকর্ডিং সম্পূর্ণরূপে নিষ্ক্রিয় করা হয়েছে। এটি মূলত পুরোনো ডিভাইসগুলোতে ব্যবহৃত হয়।
সিভিআর (ধারাবাহিক ভিডিও রেকর্ডিং) Cvr ভিডিও ২৪x৭ রেকর্ড করা হয়। এর জন্য সাবস্ক্রিপশন প্রয়োজন (যেমন, Google Google Home Premium )।
ইবিআর (ইভেন্ট ভিত্তিক রেকর্ডিং) Ebr কোনো ঘটনা (ব্যক্তি, গতি) ঘটলে রেকর্ডিং শুরু হয়। ভিডিওর দৈর্ঘ্য ঘটনার সময়কাল এবং সাবস্ক্রিপশনের উপর নির্ভর করে।
ETR (ইভেন্ট ট্রিগারড রেকর্ডিং) Etr ইভেন্টের দ্বারা চালু হওয়া সংক্ষিপ্ত প্রিভিউ রেকর্ডিং (উদাহরণস্বরূপ, ১০ সেকেন্ড)।
সরাসরি দেখুন 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(),
            )
        }
    }

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

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

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

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

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

হোম এপিআই-এর মাধ্যমে আরও বিভিন্ন সেটিংস নিয়ন্ত্রণ করা যায়।

ছবির অভিমুখ পরিবর্তন করুন

ক্যামেরার ছবির (ভিডিওর) দিক ঘোরানো যায়। ভিডিওটি শুধুমাত্র ১৮০ ডিগ্রি ঘোরানো যাবে।

ক্যামেরার ইমেজ ওরিয়েন্টেশন পরিবর্তন করতে, বিল্ট-ইন setImageRotation Kotlin ফাংশনটি ব্যবহার করে CameraAvStreamManagement ট্রেইটের imageRotation অ্যাট্রিবিউটটি আপডেট করুন:

// Change the camera's image orientation
val isRotated = false

cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }

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

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

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

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

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

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

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

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

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

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

ভিউপোর্টটি একটি ViewportStruct মধ্যে সংজ্ঞায়িত করা হয়েছে, যেটিতে চারটি মান রয়েছে, যা ভিউপোর্টের স্থানাঙ্ক হিসেবে ব্যবহৃত হয়। স্থানাঙ্কগুলো নিম্নরূপে সংজ্ঞায়িত করা হয়েছে:

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

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

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(),
    )
) }

ডিভাইস জেগে ওঠার সংবেদনশীলতা সামঞ্জস্য করুন

ডিভাইসটির ওয়েক-আপ সেনসিটিভিটি ব্যবহার করা হয় ব্যাটারি সাশ্রয়ের জন্য। এটি ডিভাইসটির কার্যকলাপ শনাক্ত করার পরিসর কমিয়ে দেয় এবং সেই কার্যকলাপ শনাক্ত করার পর জেগে ওঠার সময় বাড়িয়ে দেয়।

হোম এপিআই-গুলোতে, ডিভাইসের transportOptions এর triggerOptions এর motionSensitivity প্রপার্টি ব্যবহার করে এটি সেট করা যায়। এই অপশনগুলো প্রতিটি ডিভাইসের জন্য PushAvStreamTransport ট্রেইটের মধ্যে সংজ্ঞায়িত করা থাকে।

ওয়েক-আপ সেনসিটিভিটি শুধুমাত্র নিম্নলিখিত মানগুলিতে সেট করা যেতে পারে:

  • ১ = নিম্ন
  • ৫ = মাঝারি
  • ১০ = উচ্চ

আপডেট করার প্রক্রিয়াটি হলো, findTransport কমান্ড ব্যবহার করে সক্রিয় রেকর্ডিং স্ট্রিমগুলির ট্রান্সপোর্ট কনফিগারেশন খুঁজে বের করা, তারপর modifyPushTransport কমান্ড ব্যবহার করে নতুন সেনসিটিভিটি ভ্যালু দিয়ে কনফিগারেশনটি পরিবর্তন করা:

// Create a struct with the new wake-up sensitivity
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionSensitivity =
        OptionalValue.present(wakeUpSensitivity.toUByte())
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

সর্বোচ্চ ইভেন্টের দৈর্ঘ্য সামঞ্জস্য করুন

সর্বোচ্চ ইভেন্ট দৈর্ঘ্য হলো সেই সময়কাল, যে সময়ে ক্যামেরা কোনো একটি ইভেন্টের জন্য একটি ক্লিপ রেকর্ড করবে। হোম এপিআই (Home APIs)-এর মাধ্যমে, প্রতিটি ডিভাইসের জন্য এটিকে GHA -এর মতোই সেকেন্ডের ব্যবধানে একই দৈর্ঘ্যে কনফিগার করা যায়:

  • ১০ সেকেন্ড
  • ১৫ সেকেন্ড
  • ৩০ সেকেন্ড
  • ৬০ সেকেন্ড (১ মিনিট)
  • ১২০ সেকেন্ড (২ মিনিট)
  • ১৮০ সেকেন্ড (৩ মিনিট)

হোম এপিআই-গুলোতে, ডিভাইসের transportOptions এর triggerOptions এর motionTimeControl প্রপার্টি ব্যবহার করে এটি সেট করা যায়। এই অপশনগুলো প্রতিটি ডিভাইসের জন্য PushAvStreamTransport ট্রেইটের মধ্যে সংজ্ঞায়িত করা থাকে।

আপডেট করার প্রক্রিয়াটি হলো, findTransport কমান্ড ব্যবহার করে সক্রিয় রেকর্ডিং স্ট্রিমগুলির ট্রান্সপোর্ট কনফিগারেশন খুঁজে বের করা, তারপর modifyPushTransport কমান্ড ব্যবহার করে নতুন ইভেন্ট লেংথ ভ্যালু দিয়ে কনফিগারেশনটি পরিবর্তন করা:

// Create a struct with the new max event length
// where maxDuration is the length in seconds
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionTimeControl =
        OptionalValue.present(
          TransportMotionTriggerTimeControlStruct(maxDuration = it.toUInt())
        )
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

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

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

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

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

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