iOS-এর জন্য ক্যামেরা ডিভাইস গাইড

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

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

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

ক্যামেরা

GoogleCameraDeviceType

home.matter.6006.types.0158

এমন ডিভাইস যা স্থির ছবি বা ভিডিও ক্যাপচার করে। ক্যামেরায় অ্যাক্সেস করা যায় এমন লাইভস্ট্রিম, টু-ওয়ে টকব্য়াক বা শনাক্তকরণ ইভেন্ট থাকতে পারে।

প্রয়োজনীয় ট্রেড
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

ক্যামেরা

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

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

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

let vendorName = basicInfoTrait.attributes.vendorName!
let vendorID = basicInfoTrait.attributes.vendorID!
let productID = basicInfoTrait.attributes.productID!
let productName = basicInfoTrait.attributes.productName!
let softwareVersion = basicInfoTrait.attributes.softwareVersion!

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

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

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

// Assuming extendedBasicInformationTrait: Google.ExtendedBasicInformationTrait
let response = try await extendedBasicInformationTrait.getSerialNumber()
let serialNumber = response.serialNumber

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

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

if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp {
  self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp))
}

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

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

// 1. Get the Mount trait
guard let mountTrait = deviceType.traits[Google.MountTrait.self] else {
  print("Mount trait not supported or configured on this device.")
  return
}

// 2. Read the current mount state, detection type, and type name
let mountState         = mountTrait.attributes.mountState         // Type: Google.MountTrait.MountStateEnum?
let mountDetectionType = mountTrait.attributes.mountDetectionType // Type: Google.MountTrait.MountDetectionTypeEnum?
let mountTypeName      = mountTrait.attributes.mountTypeName      // Type: String?

// 3. Update the mount type override
try await mountTrait.update { mutableTrait in
  mutableTrait.setMountTypeOverride(.official)
}

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

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

let cameraConnectivity = cameraDeviceType.metadata.sourceConnectivity.connectivityState

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

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

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

func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
  let interfaces = trait.attributes.networkInterfaces ?? []
  var ipAddresses: [String] = []

  for interface in interfaces {
    for data in interface.iPv4Addresses {
      if let ipv4 = IPv4Address(data) {
        ipAddresses.append(String(describing: ipv4))
      }
    }
    for data in interface.iPv6Addresses {
      if let ipv6 = IPv6Address(data) {
        ipAddresses.append(String(describing: ipv6))
      }
    }
  }

  return ipAddresses
}

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

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

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

  • সেশনের জন্য SDP.
  • সেকেন্ডে সেশনের সময়সীমা।
  • সেশন আইডি, যা সেশন বাড়াতে বা বন্ধ করতে ব্যবহার করা হতে পারে।
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
  do {
    // Sending StartLiveView command
    let response = try await liveViewTrait.startLiveView(
      offerSdp: offerSdp
    )
    // Received StartLiveView response
    return (
      answerSdp: response.answerSdp,
      mediaSessionId: response.mediaSessionId,
      liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
    )
  } catch {
    // Failed to send StartLiveView command
    throw error
  }
}

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

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

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

public func extendLiveView(mediaSessionId: String) async throws {
  do {
    // Extending live view
    let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
  } catch {
    // Failed to extend live view
    throw error
  }
}

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

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

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

public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
  do {
    if isOn {
      try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
    } else {
      try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
    }
  } catch {
    throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
  }
}

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

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

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

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

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

  • কাজ করে এমন কোয়ালিটি বিকল্প রিট্রিভ করা: ডিভাইসে কাজ করে এমন উপলভ্য স্ট্রিমিং রেজোলিউশন পান । WebRtcLiveView QualityHint supportedQualityHints প্রপার্টি ব্যবহার করে কোডটি .sd, .hd, .fhd, .qhd বা .uhd-এর মতো QualityHint ভ্যালুর তালিকা হিসেবে কাজ করে এমন স্ট্রিম কোয়ালিটি দেখানোর জন্য WebRtcLiveViewট্রেইট কোয়েরি করে।

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

public var supportedQualityHints: [Google.WebRtcLiveViewTrait.QualityHint] {
  return liveViewTrait?.attributes.supportedQualityHints ?? []
}

public func updateQualityHint(
  liveViewTrait: Google.WebRtcLiveViewTrait,
  hint: Google.WebRtcLiveViewTrait.QualityHint,
  mediaSessionId: String
) async {
  do {
    _ = try await liveViewTrait.changeLiveViewQuality(
      mediaSessionId: mediaSessionId,
      qualityHint: hint
    )
  } catch {
    // error
  }
}

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

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

public func toggleIsRecording(isOn: Bool) {
  self.uiState = .loading

  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return
  }
  Task {
    do {
      try await pushAvStreamTransportTrait.setTransportStatus(
        transportStatus: isOn ? .active : .inactive)
      if isOn {
        do {
          self.player = try self.createWebRtcPlayer()
        } catch {
          // Failed to initialize WebRtcPlayer
          self.uiState = .disconnected
          return
        }
        await self.player?.initialize()
        self.uiState = .live
      } else {
        self.player = nil
        self.uiState = .off
      }
    } catch {
      // Failed to toggle onOff
    }
  }
}

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

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

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

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

public func isDeviceRecording() -> Bool {
  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return false
  }
  guard
    let hasActiveConnection =
      pushAvStreamTransportTrait
      .attributes
      .currentConnections?
      .contains(where: { $0.transportStatus == .active })
  else {
    return false
  }
  return hasActiveConnection
}

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

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

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

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

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

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

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

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

guard let cameraSnapshotTrait = deviceType.traits[
  Google.CameraSnapshotTrait.self
] else {
  print("CameraSnapshot trait not supported on this device.")
  return
}

if let previewImageUrlString = cameraSnapshotTrait
  .attributes.preview_image_url,
   let url = URL(string: previewImageUrlString) {
  // Load the preview image from the URL
}

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

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

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

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

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

do {
  let response = try await cameraSnapshotTrait.getLiveSnapshot()
  let snapshotUrlString = response.snapshot_url

  if let url = URL(string: snapshotUrlString) {
    // Load the live snapshot image from the URL
  }
} catch {
  print("Failed to get live snapshot: \(error)")
}

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

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

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

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

import UIKit

func loadSnapshotImage(from url: URL, home: Home) async -> UIImage? {
  do {
    // 1. Retrieve the OAuth access token from the Home APIs SDK
    let (accessToken, _) = try await home.permissions.authorization()

    // 2. Configure the HTTP GET request with the Bearer token
    var request = URLRequest(url: url)
    request.setValue(
      "Bearer \(accessToken)",
      forHTTPHeaderField: "Authorization"
    )

    // 3. Fetch the image data
    let (data, _) = try await URLSession.shared.data(for: request)
    return UIImage(data: data)
  } catch {
    print("Error loading snapshot image: \(error)")
    return nil
  }
}

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

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

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

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

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"
    }
  ]
}
private func setBatteryUsage(to option: UInt8) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentEnergyBalance(option)
  }
}

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

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

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

private func setAutoBatterySaver(to value: Bool) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0)
  }
}

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

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

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

self.chargingState = powerSourceTrait.attributes.batChargeState

var description: String
switch self.chargingState {
case .isCharging:
  description = "Charging"
case .isAtFullCharge:
  description = "Full"
case .isNotCharging:
  description = "Not Charging"
default:
  description = "Unknown"
}

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

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

self.batteryLevel = powerSourceTrait.attributes.batChargeLevel

var description: String
switch self.batteryLevel {
case .ok:
  description = "OK"
case .warning:
  description = "Warning"
case .critical:
  description = "Critical"
default:
  description = "Unknown"
}

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

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

if powerSourceTrait.attributes.wiredPresent ?? false {
  self.powerSourceType = .wired
} else if powerSourceTrait.attributes.batPresent ?? false {
  self.powerSourceType = .battery
} else {
  self.powerSourceType = nil
}

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

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

ব্যাটারি পাল্টানো যায় কিনা তা batReplacementNeeded অ্যাট্রিবিউট থেকে PowerSource ট্রেটের মাধ্যমে জানতে পারবেন।

// Get the battery replacement status
var batteryStatus = powerSourceTrait.attributes.batReplacementNeeded

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

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

অডিও সেটিংস

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

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

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

// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
  do {
    _ = try await self.cameraAvStreamManagementTrait?.update {
      $0.setMicrophoneMuted(!on)
    }
  } catch {
    // Error
  }
}

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

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

// Turn audio recording on or off for the device
func setAudioRecording(on: Bool) async {
  do {
    _ = try await self.cameraAvStreamManagementTrait?.update {
      $0.setRecordingMicrophoneMuted(!on)
    }
  } catch {
    // Error
  }
}

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

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

// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setSpeakerVolumeLevel(value)
    }
  } catch {
    // Error
  }
}

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

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

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

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

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

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

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

let zoneManagementTrait: Google.ZoneManagementTrait

self.zones = zoneManagementTrait.attributes.zones ?? []

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

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

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

import GoogleHomeSDK
import GoogleHomeTypes

func createFrontPorchZone(trait: Google.ZoneManagementTrait) async {
  // 1. Define the vertices for the zone (2D Cartesian coordinates)
  // Values are UInt16, typically scaled to the device's twoDCartesianMax.
  let vertices = [
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260, y = 422),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049, y = 0),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 0),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 950),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630, y = 1349),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880, y = 2048),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0, y = 2048),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638, y = 1090)
  ]

  // 2. Define the zone structure using the given SDK struct
  let newZone = Google.ZoneManagementTrait.TwoDCartesianZoneStruct(
    name: "Front Porch",
    use: [.motion], // ZoneUseEnum.motion
    vertices: vertices,
    // Color is a hex string (for example, Salmon/Pink)
    color: "#F439A0"
  )

  do {
    // 3. Execute the raw command to add the zone to the device
    // This returns the created zone's ID (UInt16).
    var newZoneID = try await trait.createTwoDCartesianZone(zone: newZone)
  } catch {
    // Error
  }
}

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

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

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16
let zone: Google.ZoneManagementTrait.TwoDCartesianZoneStruct

do {
  _ = try await zoneManagementTrait.updateTwoDCartesianZone(
        zoneID: zoneID, zone: zone)
} catch {
  // Error
}

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

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

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16

do {
  _ = try await zoneManagementTrait.removeZone(zoneID: zoneID)
} catch {
  // Error
}

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

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

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

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

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

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

iOS ডেভেলপমেন্টে, আপনি সাধারণত এইসব অ্যাট্রিবিউট পড়ার জন্য ডিভাইস থেকে AvStreamAnalysis trait অ্যাক্সেস করবেন।

// Example struct to store event triggers
public struct EventTrigger: Equatable {
  public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum
  public var enabled: Bool
}

let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait

let possibleEventTriggers = avStreamAnalysisTrait.attributes.supportedEventTriggers ?? []
let enabledEventTriggers = avStreamAnalysisTrait.attributes.enabledEventTriggers ?? []

let eventTriggers [EventTrigger] = []
for trigger in possibleEventTriggers {
  self.eventTriggers.append(
    EventTrigger(
      id: trigger,
      enabled: enabledEventTriggers.contains(trigger)
    )
  )
}

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

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

// Example struct to store event triggers
public struct EventTrigger: Equatable {
  public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum
  public var enabled: Bool
}

let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait
let eventTriggers: [EventTrigger]

let enabledEventTriggers = eventTriggers.map {
  Google.AvStreamAnalysisTrait.EventTriggerEnablement(
    eventTriggerType: $0.id,
    enablementStatus: $0.enabled ? .enabled : .disabled
  )
}

try await avStreamAnalysisTrait.setOrUpdateEventDetectionTriggers(
  eventTriggerEnablements: enabledEventTriggers
)

রেকর্ডিং মোড

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

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

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

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

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

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

// Example struct to store recording modes.
public struct RecordingMode: Hashable {
  public let id: UInt8
  public let mode: Google.RecordingModeTrait.RecordingModeEnum
}

let recordingModeTrait: Google.RecordingModeTrait

if let availableRecordingModes = recordingModeTrait.attributes.availableRecordingModes,
   let supportedRecordingModes = recordingModeTrait.attributes.supportedRecordingModes,
   let selectedRecordingMode = recordingModeTrait.attributes.selectedRecordingMode {

  var recordingModes: [RecordingMode] = []

  for recordingModeId in availableRecordingModes {
    guard Int(recordingModeId) < supportedRecordingModes.count,
          Int(recordingModeId) >= 0 else {
      // Out of bounds error
    }

    recordingModes.append(
      RecordingMode(
        id: recordingModeId,
        mode: supportedRecordingModes[Int(recordingModeId)].recordingMode,
      )
    )
  }
}

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

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

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

let recordingModeTrait: Google.RecordingModeTrait
let recordingModeID: UInt8

_ = try await recordingModeTrait.update {
  $0.setSelectedRecordingMode(recordingModeID)
}

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

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

ছবির ওরিয়েন্টেশন পরিবর্তন করা

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

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

// Change the camera's image orientation
// Value must be 0 or 180
func setImageRotation(to value: UInt16) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setImageRotation(value)
    }
  } catch {
    // Error
  }
}

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

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

// Turn night vision on or off
func setNightVision(
  to value: Google.CameraAvStreamManagementTrait.TriStateAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setNightVision(value)
    }
  } catch {
    // Error
  }
}

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

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

// Set the LED brightness
func setStatusLightBrightness(
  to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setStatusLightBrightness(value)
    }
  } catch {
    // Error
  }
}

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

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

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

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

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

func setCrop(x1: UInt16, y1: UInt16, x2: UInt16, y2: UInt16) {

  let viewport = Google.CameraAvStreamManagementTrait.ViewportStruct(
    x1: x1,
    y1: y1,
    x2: x2,
    y2: y2
  )

  Task {
    do {
      try await cameraAvStreamManagementTrait.update {
        $0.setViewport(viewport)
      }
    } catch {
      // Error
    }
  }

}

TransportOptionsStruct তৈরি করা

কিছু সেটিংসের জন্য TransportOptionsStruct-এ প্রপার্টিতে পরিবর্তন করতে হয়, যা পরে স্ট্রিমিং কানেকশনের ট্রান্সপোর্ট বিকল্পে পাস করা হয়। Swift-এর জন্য, যেকোনও প্রপার্টি আপডেট করার আগে এই স্ট্রাকচার তৈরি করতে হবে।

নিম্নলিখিত সেটিং পরিবর্তনের সাথে ব্যবহার করার জন্য struct জেনারেট করতে এই হেল্পার ফাংশন ব্যবহার করুন:

func getTransportOptions(
  transportOptions: Google.PushAvStreamTransportTrait.TransportOptionsStruct,
  wakeUpSensitivity: UInt8?,
  maxEventLength: UInt32?
) async throws
  -> Google.PushAvStreamTransportTrait.TransportOptionsStruct
{

  var newMotionTimeControl:
    Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct? = nil
  if let maxEventLength {
    guard let motionTimeControl = transportOptions.triggerOptions.motionTimeControl else {
      throw HomeError.failedPrecondition(
        // Error - cannot update max event length without motion time control
    }
    newMotionTimeControl =
      Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
        initialDuration: motionTimeControl.initialDuration,
        augmentationDuration: motionTimeControl.augmentationDuration,
        maxDuration: maxEventLength,
        blindDuration: motionTimeControl.blindDuration
      )
  }

  return Google.PushAvStreamTransportTrait.TransportOptionsStruct(
    streamUsage: .recording,
    videoStreamID: nil,
    audioStreamID: nil,
    tlsEndpointID: transportOptions.tlsEndpointID,
    url: transportOptions.url,
    triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
      triggerType: .motion,
      motionZones: nil,
      motionSensitivity: wakeUpSensitivity,
      motionTimeControl: newMotionTimeControl,
      maxPreRollLen: nil
    ),
    ingestMethod: .cmafIngest,
    containerOptions: Google.PushAvStreamTransportTrait.ContainerOptionsStruct(
      containerType: .cmaf,
      cmafContainerOptions: nil
    ),
    expiryTime: nil
  )
}

private func getRecordingConnection() async throws
  -> Google.PushAvStreamTransportTrait.TransportConfigurationStruct?
{
  guard let pushAvStreamTransportTrait else {
    // Error - PushAvStreamTransport trait not available
    return nil
  }

  let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations

  for connection in connections {
    guard let transportOptions = connection.transportOptions,
      transportOptions.streamUsage == .recording
    else {
      continue
    }

    return connection
  }

  return nil
}

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

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

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

// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
  $0.setAnalyticsEnabled(true)
}

// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
  $0.setAnalyticsEnabled(false)
}

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

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

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

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

// Assuming access to
// var pushAvStreamTransportTrait: Google.PushAvStreamTransportTrait
let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations

// Locate the connection designated for recording
let recordingConnection = connections.first { connection in
    guard let transportOptions = connection.transportOptions else { return false }
    return transportOptions.streamUsage == .recording
}

let options = recordingConnection?.transportOptions

// 1. Bandwidth Quality (Video Stream ID)
let videoStreamId = options?.videoStreamID

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

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

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

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

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

// Example: Updating to Max Quality and 30s duration
let currentOptions = recordingConnection!.transportOptions!
let newOptions = Google.PushAvStreamTransportTrait.TransportOptionsStruct(
    streamUsage: .recording,
    videoStreamID: 2, // Max Quality
    tlsEndpointID: currentOptions.tlsEndpointID,
    url: currentOptions.url,
    triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
        triggerType: .motion,
        motionSensitivity: 5, // Medium
        motionTimeControl: Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
            initialDuration: currentOptions.triggerOptions.motionTimeControl?.initialDuration ?? 10,
            augmentationDuration: currentOptions.triggerOptions.motionTimeControl?.augmentationDuration ?? 5,
            maxDuration: 30,
            blindDuration: currentOptions.triggerOptions.motionTimeControl?.blindDuration ?? 0
        )
    ),
    ingestMethod: currentOptions.ingestMethod,
    containerOptions: currentOptions.containerOptions
)

try await pushAvStreamTransportTrait.modifyPushTransport(
    connectionID: recordingConnection!.connectionID,
    transportOptions: newOptions
)

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

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

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

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

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

লেবেল ভ্যালু (UInt8)
কম 1
মাঝারি 5
বেশি 10

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

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

  • ১০, ১৫, ৩০, ৬০, ১২০, ১৮০

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

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

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