iOS-এ Structure API

iOS-এর জন্য Home API-এর মাধ্যমে Structure API অ্যাক্সেস করা যেতে পারে।

Structure API-এর সাথে কাজ করতে, প্রথমে আপনার অ্যাপে GoogleHomeSDK প্যাকেজ ইমপোর্ট করুন:

import GoogleHomeSDK

সমস্যা ম্যানেজ করা

Home API-এর কিছু পদ্ধতি HomeError থ্রো করে, তাই আমরা সাজেস্ট করি যে আপনি সেইসব কলে HomeError ক্যাচ করার জন্য do-catch ব্লক ব্যবহার করুন।

HomeError হ্যান্ডেল করার সময়, কী সমস্যা হয়েছে তা জানতে এর code এবং message ফিল্ড চেক করুন।

কোনও সমস্যা সমাধান না করা হলে আপনার অ্যাপ ক্র্যাশ করবে।

আরও তথ্যের জন্য, সমস্যা সমাধান দেখুন।

Structure API

Home Home গ্রাফকে দেখায় এবং এটি Structure API-এর এন্ট্রি পয়েন্ট। এটি স্ট্রাকচার, রুম ও ডিভাইসের রেফারেন্স প্রদান করে।

Structure আপনার হোম গ্রাফে একটি স্ট্রাকচারকে দেখায়। এটি id ও name-এর মতো স্ট্রাকচার মেটাডেটা অ্যাক্সেস করার সুবিধা দেয়।

আপনার অ্যাকাউন্টে সব স্ট্রাকচার পেতে structures() ব্যবহার করুন। স্ট্রাকচারগুলি Query-এর আকারে ফেরত দেওয়া হয়, যা এর ডেটা ব্যবহার করার পদ্ধতির বিকল্প অফার করে:

API বিবরণ
stream() একটি Publisher রিটার্ন করে যা পরিবর্তন হওয়ার সাথে সাথে প্রতিটি অবজেক্ট আলাদাভাবে এমিট করে।
batched() Publisher দেখায় যা অবজেক্টের Set হিসেবে বর্তমান ফলাফল প্রকাশ করে। প্রতিটি নির্গত Set অবজেক্ট গ্রাফের বর্তমান অবস্থাকে দেখায়।
list() অবজেক্টের Set হিসেবে বর্তমান ফলাফল দেখায়।

structures().list() কল হয়ত সাথে সাথে স্ট্রাকচারের সঠিক সেট ফেরত দেবে না। আপনার অ্যাপ যদি রিঅ্যাক্টিভ হয় এবং UI চালানোর জন্য সব স্ট্রাকচার পরিবর্তন সাবস্ক্রাইব করতে stream() কল করে, তাহলে স্ট্রাকচারের একটি সঠিক তালিকা অবশেষে ফেরত দেওয়া উচিত। অন্যান্য পরিস্থিতিতেও স্ট্রাকচারের খালি তালিকা ফেরত আসতে পারে, যেমন ব্যবহারকারীর ফোনের কানেক্টিভিটি চলে গেলে অথবা ব্যবহারকারী আপনার অ্যাপের অনুমতি প্রত্যাহার করে নিলে। আপনার অ্যাপে এইসব পরিস্থিতি ম্যানেজ করার ব্যবস্থা রাখতে হবে।

@Published public private(set) var structures: [Structure] = []
private var structuresCancellable: AnyCancellable?

  self.structuresCancellable = home
    .structures()
    .batched()
    .receive(on: DispatchQueue.main)
    .map { Array($0) }
    .catch {
      // Failed to load structures
      return Just([Structure]())
    }
    .assign(to: \.structures, on: self)

স্যাম্পেল স্ট্রাকচার কল

স্ট্রাকচারের একটি সেট পান

Query<Structure>-এ list() কল করলে, সবচেয়ে সাম্প্রতিক সেট অফ এলিমেন্ট ফেরত পাওয়া যায়:

// Get a stream of all structures accessible to the user
let allStructuresChanges = self.home.structures()
let allStructures = try? await allStructuresChanges.list()

রিঅ্যাক্টিভ অ্যাপ ডিজাইন করার সময়, আপনি list()-এর পরিবর্তে batched() এবং stream() কল ব্যবহার করতে চাইবেন, কারণ হোম গ্রাফ পরিবর্তন হলে এগুলি অটোমেটিক ডেটা তৈরি করে।

স্ট্রাকচার প্রপার্টি পান

স্ট্রাকচারের তালিকা হাতে থাকলে, আপনি সেগুলির জন্য প্রপার্টি অ্যাক্সেস করতে পারবেন:

// Get a stream of changes taking place on a structure.
let structureChanges = try await home.structures().list().filter { $0.id == structureID }

// Get a snapshot of the structure.
let structure = structureChanges.first!

// Get structure properties
print("id \(structure.id) ")
print("name \(structure.name) ")

নাম দিয়ে কোনও স্ট্রাকচার খুঁজুন

আপনি যদি কোনও স্ট্রাকচারের নাম জানেন, তাহলে আপনি name প্রপার্টি ব্যবহার করেও এটি অ্যাক্সেস করতে পারবেন:

do {
  structure1 = try await home.structures().list().first(where: { $0.name == "Main House" })
} catch let _ as HomeError {
  // Code for handling the exception
}

সেখান থেকে, প্রতিটি স্ট্রাকচারের জন্য প্রপার্টি, রুম ও ডিভাইস অ্যাক্সেস করা যায়।

একাধিক স্ট্রাকচার নিয়ে কাজ করা

একাধিক স্ট্রাকচার ব্যবহার করতে, প্রতিটি স্ট্রাকচারের জন্য আলাদা রেফারেন্স পান:

var structure1: Structure!
var structure2: Structure!
do {
  structure1 = try await home.structures().list().first(where: { $0.name == "Main House" })
} catch let _ as HomeError {
  // Code for handling the exception
}
do {
  structure2 = try await home.structures().list().first(where: { $0.name == "Guest Cottage" })
} catch let _ as HomeError {
  // Code for handling the exception
}

রুম

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

অ্যাকাউন্টে সব রুমের তথ্য পেতে Home.rooms() ব্যবহার করুন, তারপর প্রতিটি রুমে সংশ্লিষ্ট ডিভাইসগুলি দেখাতে roomID = device.roomID ব্যবহার করুন।

self.home.rooms().batched()
  .combineLatest(self.home.devices().batched())
  .receive(on: DispatchQueue.main)
  .catch { error in
    // Failed to load rooms and devices
    return Just((Set<Room>(), Set<HomeDevice>()))
  }
  .map { rooms, devices in
    var devicesByRoom = [Room: [HomeDevice]]()
    for room in rooms where room.structureID == currentStructureID {
      devicesByRoom[room] = devices.filter { $0.roomID == room.id }
    }
    return devicesByRoom
  }.assign(to: &self.$devicesByRoom)

Sample Room কল

রুমের তালিকা পান

Home ক্লাস ব্যবহার করে, আপনি রুমের তালিকা পেতে এবং সেগুলির জন্য প্রপার্টি অ্যাক্সেস করতে পারবেন:

let allRoomsChanges = self.home.rooms()
let allRooms = try await allRoomsChanges.list()
let room = allRooms.first!
XCTAssertTrue(allRooms.contains(room))

print("id \(room.id) ")
print("name \(room.name) ")

রুম তৈরি করুন

Structure-এ নতুন রুম তৈরি করতে:

let testName = "Test Room Name"
var newRoom: Room!
do {
  newRoom = try await structure.createRoom(name: testName)
  XCTAssertNotNil(newRoom)
} catch let _ as HomeError {
  // Code for handling the exception
}

রুম মুছে দেওয়া

অথবা, আপনি অন্যভাবেও রুম মুছে দিতে পারেন:

val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull()
    structure.deleteRoom(roomToDelete!!)

এছাড়াও, আপনি রুমের আইডি ব্যবহার করে সেটি মুছে দিতে পারবেন:

let roomToDelete = allRooms.first(where: { $0.id == room.id })
if let roomToDelete1 = roomToDelete {
  do {
    try await structure.deleteRoom(roomToDelete1)
  } catch let _ as HomeError {
    // Code for handling the exception
  }
}

ডিভাইস সহ কোনও রুম মুছে দেওয়া হলে, ডিভাইসগুলি স্ট্রাকচারে থেকে যাবে কিন্তু কোনও রুমে আর অ্যাসাইন করা থাকবে না।

ডিভাইস অন্য রুমে সরানো

এছাড়াও, Structure আপনাকে অন্য রুমে ডিভাইস সরানোর অনুমতি দেয়:

do {
  try await structure.move(device: light, to: room)
} catch let _ as HomeError {
  // Code for handling the exception
}

রুমের নাম পরিবর্তন করা

রুমের নাম পরিবর্তন করতে setName(_:) মেথড কল করুন:

let updatedRoom = try await theRoom.setName("new room name")

কোনও রুমের নাম পরিবর্তন করার সময়, আসল Room স্ট্রাক্ট একই থাকে এবং পরিবর্তনটি রিটার্ন করা আপডেট হওয়া Room অবজেক্টে দেখা যায়।

নাম ৬০টি ইউনিকোড কোড পয়েন্ট (অক্ষর) সীমার বেশি হলে তা ছোট করা হবে এবং কোনও সমস্যা দেখানো হবে না। দীর্ঘ নাম ম্যানেজ করার দায়িত্ব ডেভেলপারদের এবং, উদাহরণস্বরূপ, তারা সিদ্ধান্ত নিতে পারেন যে ব্যবহারকারীদের নাম ছোট করা হবে কিনা।

ডিভাইস গ্রুপ

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

ফিজিক্যাল রুমের মতো, ডিভাইস গ্রুপ একটি স্ট্রাকচারের অন্তর্গত। তবে, রুমের মতো নয়, ডিভাইস গ্রুপ হল লজিক্যাল গ্রুপিং। একটি ডিভাইস একই সাথে একাধিক ডিভাইস গ্রুপের অংশ হতে পারে। ডিভাইস গ্রুপে সর্বাধিক ১০০টি ডিভাইস থাকতে পারে।

ডিভাইস গ্রুপকে DeviceGroup এন্টিটি দ্বারা দেখানো হয়, যা HomeDevice থেকে আলাদা। ডিভাইস গ্রুপের সাথে ইন্টার‍্যাক্ট করতে, Home.configure-এ ReferencedAutomationTypes কনফিগার করার সময় প্রাসঙ্গিক ডিভাইসের ধরন ও বৈশিষ্ট্য অন্তর্ভুক্ত করুন, এর সাথে GroupTrait, GroupManagementTrait এবং GroupMembershipTrait বৈশিষ্ট্যও অন্তর্ভুক্ত করুন।

আপনি কোনও গ্রুপের ডিভাইসের সাথে ইন্টার‍্যাক্ট করতে পারেন, হয় সরাসরি এর মেম্বার ডিভাইসের উপর ইটারেট করে (দেখুন গ্রুপ মেম্বার ডিভাইসের সাথে ইন্টার‍্যাক্ট করুন) অথবা DeviceGroup-এ ডিভাইসের ধরনের অংশকে টার্গেট করে (দেখুন ডিভাইস গ্রুপ কন্ট্রোল করুন)।

ডিভাইস গ্রুপের তালিকা পান

হোমের সব ডিভাইস গ্রুপ সম্পর্কে কোয়েরি করতে:

let groups = try await home.entities(DeviceGroup.self).list()
for group in groups {
  let groupTrait = await group.traits.get(Google.GroupTrait.self)
  let name = groupTrait?.attributes.name ?? "Device Group"
  print("Found group: \(name) with ID: \(group.id)")
}

গ্রুপ মেম্বারের ডিভাইসের সাথে ইন্টার‍্যাক্ট করা

গ্রুপের মেম্বার ডিভাইসের উপর ইটারেট করলে আপনি প্রতিটি মেম্বারের উপর সূক্ষ্ম কন্ট্রোল পান, একটি অনুরোধে কমান্ড ব্যাচ করতে পারেন এবং মেম্বারদের মধ্যে অ্যাট্রিবিউট অ্যাগ্রিগেট বা লিখতে পারেন।

প্রথমে, টার্গেট গ্রুপ আইডির জন্য প্রতিটি ডিভাইসের GroupMembershipTrait চেক করে হোমে থাকা ডিভাইস ফিল্টার করুন:

let allDevices = try await home.devices().list()
var members: [HomeDevice] = []
for device in allDevices {
  if let membership = await device.traits.get(
    Google.GroupMembershipTrait.self
  ),
  membership.attributes.groupObjectIdsArray.contains(group.id) {
    members.append(device)
  }
}

গ্রুপের সব মানানসই মেম্বারদের জন্য কোনও ট্রেইটের কমান্ড সহ একটি ব্যাচ করা অনুরোধ পাঠাতে:

var onOffTraits: [Matter.OnOffTrait] = []
for device in members {
  if let light = await device.types.get(OnOffLightDeviceType.self),
     let onOff = light.matterTraits.onOffTrait {
    onOffTraits.append(onOff)
  }
}

let traitsToUse = onOffTraits
let responses = try await home.sendBatchedCommands { batcher in
  return try traitsToUse.map { batcher.add(try $0.onBatchable()) }
}

for response in responses {
  try response.getOrThrow()
}

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

try await withThrowingTaskGroup(of: Void.self) { taskGroup in
  taskGroup.addTask {
    try await Task.sleep(for: .seconds(5))
    throw CancellationError()
  }

  for device in members {
    taskGroup.addTask {
      guard let light = await device.types.get(DimmableLightDeviceType.self),
            let levelControl = light.matterTraits.levelControlTrait,
            levelControl.attributes.$onTransitionTime.isSupported
      else { return }
      _ = try await levelControl.update {
        $0.setOnTransitionTime(1)
      }
    }
  }

  for _ in 0..<members.count {
    try await taskGroup.next()
  }
  taskGroup.cancelAll()
}

গ্রুপের মেম্বারদের মধ্যে কোনও অ্যাট্রিবিউট অ্যাগ্রিগেট করতে, যেমন গ্রুপের সব কালার টেম্পারেচার লাইটের মধ্যে ন্যূনতম colorTempPhysicalMaxMireds খোঁজা:

var maxMiredsValues: [UInt16] = []
for device in members {
  if let light = await device.types.get(ColorTemperatureLightDeviceType.self),
     let mireds = light.matterTraits.colorControlTrait?.attributes
       .colorTempPhysicalMaxMireds {
    maxMiredsValues.append(mireds)
  }
}
let minMaxMireds = maxMiredsValues.min()

ডিভাইস গ্রুপ তৈরি করা

ডিভাইস গ্রুপ তৈরি করতে স্ট্রাকচারে GroupManagementTrait ব্যবহার করুন:

let groupsManagementTrait =
  try await structure.traits(Google.GroupManagementTrait)
let _ = try await groupsManagementTrait.createUserDefinedGroup(
  withName: "Kitchen Lights",
  withDevices: [light1, light2]
)

গ্রুপ মেম্বারশিপ ম্যানেজ করা

আগে থেকে থাকা গ্রুপে মেম্বার যোগ করতে:

let groupManagementTrait =
  try await structure.traits(Google.GroupManagementTrait.self)
groupManagementTrait.addGroupMembers(
  groupObjectId: group.id,
  memberDeviceObjectIds = [light3.id],
)

গ্রুপ থেকে মেম্বারদের সরাতে:

let groupManagementTrait =
  try await structure.traits(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.removeGroupMembers(
  groupObjectId: group.id,
  memberDeviceObjectIdsArray: Array(removedIDs)
)

ডিভাইস গ্রুপের নাম পরিবর্তন করা

ডিভাইস গ্রুপের নাম পরিবর্তন করতে, GroupTrait-এর name ফিল্ড আপডেট করুন:

let groupTrait = group.traits.get(Google.GroupTrait.self)
_ = try await groupTrait.update { $0.name = "Movie Corner" }

ডিভাইস গ্রুপ মুছে দেওয়া

কোনও স্ট্রাকচার থেকে ডিভাইস গ্রুপ মুছে দিতে:

let groupManagementTrait =
  try await structure.traits.get(Google.GroupManagementTrait.self)

_ = try await groupManagementTrait.deleteGroup(groupObjectId: group.id)