iOS এর জন্য ডোরবেল ডিভাইস নির্দেশিকা

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

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

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

ডোরবেল

Google Doorbell DeviceType

home.matter.6006.types.0113

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

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

ডোরবেল

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

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

// [START get_device_information]
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!
// [END get_device_information]

ক্রমিক নম্বরটি নিন

ডিভাইসের সিরিয়াল নম্বর পেতে, 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 lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

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

ডিভাইসটির আইপি অ্যাড্রেসটি নিন

ডিভাইসটির আইপি অ্যাড্রেস খুঁজে বের করতে, 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
}

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

একটি লাইভস্ট্রিম শুরু করতে, 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
  }
}

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

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

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

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

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

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

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

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

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

  • লাইভস্ট্রিমের কোয়ালিটি পরিবর্তন করুন: সক্রিয় লাইভস্ট্রিমের স্ট্রিমিং রেজোলিউশন পরিবর্তন করতে (উদাহরণস্বরূপ, স্ট্যান্ডার্ড ডেফিনিশন থেকে হাই ডেফিনিশনে পরিবর্তন করতে) একটি নির্বাচিত 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
  }
}

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

ক্যামেরার রেকর্ডিং ক্ষমতা চালু করতে, 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
}

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

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

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

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

এই ফিচারটি 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)
  }
}

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

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

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

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

ডিভাইসটির বর্তমান চার্জিং অবস্থা (চার্জ হচ্ছে, সম্পূর্ণ চার্জ হয়েছে, বা চার্জ হচ্ছে না) জানতে, 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
}

অডিও সেটিংস

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

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

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

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

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
)

রেকর্ডিং মোড

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
}

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

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

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

// 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 প্রপার্টিটি একটি নির্দিষ্ট ভিডিও স্ট্রিম কনফিগারেশনকে নির্দেশ করে।

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

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

TransportTriggerOptionsStruct এর motionSensitivity প্রপার্টিটি নিম্নলিখিত মানগুলির সাথে সঙ্গতিপূর্ণ:

লেবেল মান (UInt8)
নিম্ন
মাঝারি
উচ্চ ১০

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

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

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

ঘণ্টার শব্দ সেটিংস

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

ঘণ্টার ধ্বনি পরিবর্তন করুন

ডোরবেলের চিম সাউন্ড পরিবর্তন করতে, প্রথমে 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
  }
}

বাহ্যিক ঘণ্টা ব্যবহার করুন

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

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

// 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 APIs)-এর মাধ্যমে কনফিগার করা যেতে পারে। যদি এক্সটার্নাল চাইমটি একটি নির্দিষ্ট সময়কাল (chime duration) সমর্থন করে, তবে একজন ব্যবহারকারী এটি কনফিগার করতে চাইতে পারেন।

এখানে নির্ধারিত মানটি বাহ্যিক চাইমটির নিজস্ব বৈশিষ্ট্য এবং এর প্রস্তাবিত শব্দকালের উপর নির্ভর করে।

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

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

একটি চিম থিম সক্রিয় করুন

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

কোনো ব্যবহারকারীর জন্য কোন কোন চাইম থিম উপলব্ধ আছে তা দেখতে, একটি টাইমবক্স ফিল্টার তৈরি করুন এবং 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)
  }
}

দর্শনার্থী ঘোষণা সেটিংস

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

নিম্নলিখিত উদাহরণটি দেখায় যে ভিজিটর ঘোষণাগুলি সক্রিয় আছে কিনা তা কীভাবে পরীক্ষা করতে হয় এবং এই সেটিংটি কীভাবে আপডেট করতে হয়:

let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled

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