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

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

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

Home API ডিভাইসের ধরন বৈশিষ্ট্য Swift স্যাম্পেল অ্যাপ ব্যবহারিক ক্ষেত্র

কলিং বেল

GoogleDoorbellDeviceType

home.matter.6006.types.0113

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

প্রয়োজনীয় বৈশিষ্ট্য
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

কলিং বেল

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

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

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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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

দ্রুত প্রতিক্রিয়া

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

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

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

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

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


import GoogleHomeSDK
import GoogleHomeTypes

func playDoorbellPresetMessage(device: HomeDevice, phraseTypeString: String) async {
    // 1. Retrieve the GoogleDoorbellDeviceType helper on the device
    guard let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) else {
        print("This device is not a Google Doorbell or is currently uninitialized.")
        return
    }

    // 2. Extract the Google.PresetMessageTrait
    guard let presetMessageTrait = doorbellDeviceType.traits[Google.PresetMessageTrait.self] else {
        print("PresetMessageTrait is not supported on this device.")
        return
    }

    // 3. (Optional) Check available phrase types supported by the device
    if let availablePhrases = presetMessageTrait.attributes.availablePhraseTypes {
        let phraseTypeNames = availablePhrases.map { $0.phraseType }
        print("Supported quick response phrases: \(phraseTypeNames)")
    }

    // 4. Send the playPresetMessage command asynchronously
    do {
        try await presetMessageTrait.playPresetMessage(phraseType: phraseTypeString)
        print("Preset message successfully requested.")
    } catch {
        print("SDK error occurred playing preset message: \(error)")
    }
}

কথা বলার ভাষা সেট করুন

কথা বলার ভাষা সেট করুন

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

// Setting the active language
// Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait
let selectedLocale = "en_US"
try await localizationConfigurationTrait.update {
    $0.setActiveLocale(selectedLocale)
}

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

ডিভাইসটি ক্লাউডের সাথে সবচেয়ে সম্প্রতি কখন যোগাযোগ করেছিল তা জানতে, 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 doorbellConnectivity = doorbellDeviceType.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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

লাইভস্ট্রিম শুরু করতে, সেশন ডেসক্রিপশন প্রোটোকল (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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

টকব্যাক শুরু করতে, 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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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

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

  • কাজ করে এমন কোয়ালিটির বিকল্প ফিরিয়ে আনা: ডিভাইসে কাজ করে এমন উপলভ্য স্ট্রিমিং রেজোলিউশন পান। কোডটি WebRtcLiveView বৈশিষ্ট্যকে কোয়েরি করে যাতে QualityHint মান (যেমন .sd, .hd, .fhd, .qhd বা .uhd) হিসেবে কাজ করে এমন স্ট্রিম কোয়ালিটি প্রকাশ করা যায়। এর জন্য supportedQualityHints প্রপার্টি ব্যবহার করা হয়।

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

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

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

ক্যামেরার রেকর্ডিং ক্ষমতা চালু করতে, PushAvStreamTransportTrait বৈশিষ্ট্যের setTransportStatus(transportStatus:optionalArgsProvider:) পদ্ধতিতে TransportStatusEnum.Active পাস করুন। রেকর্ডিংয়ের ক্ষমতা বন্ধ করতে, এটি পাস করুন 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
    }
  }
}

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

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

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

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

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

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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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

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

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

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

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

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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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

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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

এই ফিচার কনফিগার করতে, 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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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 অ্যাট্রিবিউট থেকে বোঝা যায় যে ব্যাটারি পরিবর্তন করা যাবে না, ব্যবহারকারী পরিবর্তন করতে পারবেন নাকি ফ্যাক্টরি-রিপ্লেসেবল।

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

// 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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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 বৈশিষ্ট্য অ্যাক্সেস করবেন।

// 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-এর জন্য স্যাম্পেল অ্যাপে প্রয়োগ করা হয়েছে   

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

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

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

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

let recordingModeTrait: Google.RecordingModeTrait
let recordingModeID: UInt8

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

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

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

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

ক্যামেরার জন্য নাইট ভিশন চালু বা বন্ধ করতে, বিল্ট-ইন 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-এর উজ্জ্বলতা পরিবর্তন করতে, ThreeLevelAutoEnum ব্যবহার করে statusLightBrightness বিল্ট-ইন setStatusLightBrightness ফাংশন ব্যবহার করে CameraAvStreamManagementTrait অ্যাট্রিবিউট আপডেট করুন:

// 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 এবং ক্যামেরা ইমপ্লিমেন্টেশনের উপর নির্ভর করে। একদম প্রাথমিক লেভেলে, ক্যামেরা ভিডিওর ভিউপোর্ট সেট করতে, CameraAvStreamManagementTrait ট্রেইটের viewport অ্যাট্রিবিউটকে 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-এর জন্য, কোনও প্রপার্টি আপডেট করার আগে এই স্ট্রাক্ট তৈরি করতে হবে।

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

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 ক্লাউডে বিস্তারিত অ্যানালিটিক্স ডেটা পাঠানোর জন্য অপ্ট-ইন করতে পারে (Home API-এর জন্য ক্লাউড মনিটরিং দেখুন)।

কোনও ডিভাইসের জন্য অ্যানালিটিক্স চালু করতে, ExtendedGeneralDiagnosticsTrait-এর analyticsEnabled) প্রপার্টি 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
)

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

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

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

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

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

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

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

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

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

চাইম সেটিংস

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

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

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

doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
  return chimeSound.chimeID, chimeSound.name
}

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

func setDoorbellChime(chimeID: UInt8) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setSelectedChime(chimeID)
    }
  } catch {
    // Error
  }
}

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

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

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

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

// Indicate the external chime is mechanical
func setExternalChime(to value: Google.ChimeTrait.ExternalChimeType) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChime(value)
    }
  } catch {
    // Error
  }
}

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

Home API-এর মাধ্যমে এক্সটার্নাল চাইম কত সেকেন্ড ধরে বাজবে তা কনফিগার করা যেতে পারে। এক্সটার্নাল চাইমে চাইম বাজানোর সময়সীমা সেট করার সুবিধা থাকলে, ব্যবহারকারী এটি কনফিগার করতে চাইতে পারেন।

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

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

// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChimeDuration(value)
    }
  } catch {
    // Error
  }
}

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

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

কিছু কলিং বেলে এমন চাইম থাকতে পারে যা ব্যবহারকারীরা শুধুমাত্র সীমিত সময়ের জন্য ব্যবহার করতে পারবেন। যেমন, ছুটির দিনের জন্য নির্দিষ্ট চাইম। এগুলিকে চাইম থিম বলা হয়।

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

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

let chimeThemes = try await chimeThemeTrait.getAvailableThemes().themes

if !chimeThemes.isEmpty {
  var chimeThemeSettings = []
  for chimeTheme in chimeThemes {
    let currentDateTime = UInt64(Date().timeIntervalSince1970)

    // Only show chime themes that are active.
    if chimeTheme.startTimeSeconds ?? 0 &lt;= currentDateTime
      &amp;&amp; chimeTheme.endTimeSeconds ?? UInt64.max &gt;= currentDateTime
    {
      self.chimeThemeSettings.append(chimeTheme.name)
    }
  }
}

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

private func setChimeTheme(to value: String) async throws {
  _ = try await chimeThemeTrait.update {
    $0.setSelectedTimeboxedThemeName(value)
  }
}

অতিথি আগমনের বিজ্ঞপ্তি সংক্রান্ত সেটিংস

আপনি Home API-এর VisitorAnnouncement বৈশিষ্ট্য ব্যবহার করে ডোরবেলের জন্য অতিথি আগমনের বিজ্ঞপ্তি সেটিংস কোয়েরি ও ম্যানেজ করতে পারবেন। কেউ কলিং বেল বাজালে, Google স্মার্ট স্পিকার বা ডিসপ্লেতে কোনও ভিজিটরের উপস্থিতি ঘোষণা করা হবে কিনা তা এই বৈশিষ্ট্য নিয়ন্ত্রণ করে।

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

let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled

let value: Bool
_ = try await self.visitorAnnouncementTrait?.update {
  $0.setVisitorAnnouncementsEnabled(value)
}

ডিভাইস ডিকমিশন করা

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

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