يتم تنفيذ نوع الجهاز "جرس الباب" باستخدام سمتَين:
PushAvStreamTransportTrait،
التي تتعامل مع نقل بث الصوت والفيديو باستخدام بروتوكولات مستندة إلى الإرسال، و
WebRtcLiveViewTrait،
التي تتيح التحكّم في البث المباشر ووظيفة "التحدّث والاستماع".
يجب دائمًا التحقّق من توفّر السمات والأوامر لجهاز معيّن قبل استخدام أي ميزات أو محاولة تعديل السمات. لمزيد من المعلومات، اطّلِع على مقالة التحكّم في الأجهزة علىiOS.
| نوع الجهاز في Home APIs | السمات | تطبيق Swift النموذجي | حالة الاستخدام |
|---|---|---|---|
|
جرس الباب
جهاز يتم تشغيله بواسطة زر خارج الباب ويصدر إشارة مسموعة و/أو مرئية، ويُستخدم لطلب انتباه شخص موجود في مكان ما على الجانب الآخر من الباب. قد تتضمّن أجراس الأبواب عمليات بث مباشر يسهل الوصول إليها أو ميزة التحدّث ثنائي الاتجاه أو أحداث الرصد. |
السمات المطلوبة google PushAvStreamTransportTrait google 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]
الحصول على الرقم التسلسلي
للحصول على الرقم التسلسلي للجهاز، استخدِم الأمر
GetSerialNumber الخاص بالسمة
ExtendedBasicInformation.
يعرض المثال حفظ الرقم التسلسلي في متغيّر اسمه 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)")
}
}
ضبط اللغة المحكية
ضبط اللغة المحكية
اضبط اللغة المنطوقة النشطة على الجهاز على لغة محلية معيّنة
(مثل "en_US") باستخدام طريقة setActiveLocale من السمة
LocalizationConfiguration.
// Setting the active language // Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait let selectedLocale = "en_US" try await localizationConfigurationTrait.update { $0.setActiveLocale(selectedLocale) }
الحصول على آخر وقت تم فيه التواصل مع السحابة الإلكترونية للجهاز
للعثور على آخر مرة تواصل فيها الجهاز مع السحابة الإلكترونية، استخدِم السمة lastContactTimestamp الخاصة بالسمة ExtendedGeneralDiagnostics:
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 القياسية
متاحة على الإنترنت بسبب التوجيه المحلي، ولكن ستكون السمات المستندة إلى السحابة الإلكترونية
غير متاحة.
الحصول على عنوان IP للجهاز
للعثور على عنوان IP الخاص بالجهاز، استخدِم السمة networkInterfaces الخاصة بالعنصر GeneralDiagnosticsTrait.
يتم عرض العناوين كعناصر Data، ويمكنك تنسيقها كسلاسل IPv4 أو IPv6 عادية باستخدام إطار عمل Network:
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
}
بدء بث مباشر
لبدء بث مباشر، أرسِل سلسلة Session Description Protocol (SDP) إلى طريقة startLiveView(offerSdp:) في السمة WebRtcLiveViewTrait، والتي تعرض ثلاث قيم:
- تمثّل هذه السمة وصف الجلسة (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
}
}
بدء TalkBack وإيقافه
لبدء TalkBack، استدعِ طريقة startTalkback(mediaSessionId:optionalArgsProvider:) في السمة WebRtcLiveViewTrait.
لإيقاف التسجيل، استخدِم 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لعرض جودات البث المتوافقة على شكل قائمة بقيمQualityHint(مثل.sdأو.hdأو.fhdأو.qhdأو.uhd) باستخدام السمةsupportedQualityHints.تغيير جودة البث المباشر: تطبيق
QualityHintمحدّد لتغيير دقة البث المباشر النشط (على سبيل المثال، التبديل من الدقة العادية إلى الدقة العالية) تستخدم الدالةupdateQualityHintطريقةchangeLiveViewQualityالخاصة بسمةWebRtcLiveViewلتطبيق إعدادات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 } }
تفعيل ميزة التسجيل وإيقافها
لتفعيل إمكانية التسجيل في الكاميرا، مرِّر
TransportStatusEnum.Active
إلى طريقة
PushAvStreamTransportTrait
في السمة
setTransportStatus(transportStatus:optionalArgsProvider:). لإيقاف إمكانية التسجيل، مرِّر القيمة
TransportStatusEnum.Inactive.
في المثال التالي، نضمّن هذه المكالمات في مكالمة واحدة تستخدم Boolean لتبديل إمكانية التسجيل:
public func toggleIsRecording(isOn: Bool) {
self.uiState = .loading
guard let pushAvStreamTransportTrait else {
// PushAvStreamTransportTrait not found.
return
}
Task {
do {
try await pushAvStreamTransportTrait.setTransportStatus(
transportStatus: isOn ? .active : .inactive)
if isOn {
do {
self.player = try self.createWebRtcPlayer()
} catch {
// Failed to initialize WebRtcPlayer
self.uiState = .disconnected
return
}
await self.player?.initialize()
self.uiState = .live
} else {
self.player = nil
self.uiState = .off
}
} catch {
// Failed to toggle onOff
}
}
}
إنّ تفعيل ميزة التسجيل في الكاميرا أو إيقافها هو نفسه تشغيل فيديو الكاميرا أو إيقافه. وعندما يكون فيديو الكاميرا مفعّلاً، يتم التسجيل (لأغراض الأحداث والمقاطع ذات الصلة).
عندما تكون إمكانية التسجيل غير مفعَّلة (يكون فيديو الكاميرا متوقفًا):
- سيظل بإمكان الكاميرا الظهور على أنّها متصلة بالإنترنت وفقًا
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
}
إعدادات البطارية
يمكن التحكّم في إعدادات البطارية المختلفة من خلال واجهات برمجة التطبيقات لمنزل Google.
ضبط إعدادات استخدام البطارية المفضَّلة
يسمح لك ضبط توازن الطاقة بتحديد المفاضلة بين عمر البطارية وأداء الجهاز. يمكنك إنشاء ملفات شخصية مختلفة للبطارية، مثل "عمر بطارية أطول" و"متوازن" و "أداء أفضل"، والتبديل بينها.
يتم تنفيذ هذه الميزة من خلال تعديل السمة
currentEnergyBalance
لنوع البيانات EnergyPreference. تقبل السمة فهرسًا عدديًا صحيحًا يتوافق مع ملف شخصي محدّد في قائمة energyBalances الخاصة بالجهاز (على سبيل المثال، 0 لـ EXTENDED و1 لـ BALANCED و2 لـ PERFORMANCE).
تشير القيمة null في currentEnergyBalance إلى أنّ الجهاز يستخدم ملفًا شخصيًا مخصّصًا. هذه حالة للقراءة فقط.
يوضّح ما يلي مثالاً على بنية ستستخدمها السمة 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) } }
تفعيل ميزة "توفير شحن البطارية تلقائيًا"
لضبط هذه الميزة، عدِّل السمة
currentLowPowerModeSensitivity
في السمة EnergyPreference. تستخدم هذه السمة فهرسًا لاختيار مستوى حساسية، حيث يمثّل 0 عادةً Disabled، ويمثّل 1 Enabled أو Automatic.
private func setAutoBatterySaver(to value: Bool) async throws { _ = try await energyPreferenceTrait.update { $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0) } }
الحصول على حالة شحن البطارية
للحصول على حالة الشحن الحالية للجهاز (جارٍ الشحن أو مشحون بالكامل أو لا يتم الشحن)، استخدِم السمة batChargeState الخاصة بسمة PowerSource.
self.chargingState = powerSourceTrait.attributes.batChargeState var description: String switch self.chargingState { case .isCharging: description = "Charging" case .isAtFullCharge: description = "Full" case .isNotCharging: description = "Not Charging" default: description = "Unknown" }
الحصول على مستوى البطارية
للحصول على مستوى البطارية الحالي، استخدِم السمة
batChargeLevel
الخاصة بالسمة
PowerSource. يكون المستوى إما 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" }
الحصول على مصدر الطاقة
لتحديد مصدر الطاقة الذي يستخدمه الجهاز، استخدِم السمتَين BatPresent وwiredPresent ضمن السمة PowerSource.
if powerSourceTrait.attributes.wiredPresent ?? false { self.powerSourceType = .wired } else if powerSourceTrait.attributes.batPresent ?? false { self.powerSourceType = .battery } else { self.powerSourceType = nil }
إعدادات الصوت
يمكن التحكّم في إعدادات الصوت المختلفة من خلال واجهات برمجة التطبيقات Home APIs.
تفعيل الميكروفون أو إيقافه
لتفعيل ميكروفون الجهاز أو إيقافه، عدِّل السمة
microphoneMuted
لسمة CameraAvStreamManagementTrait باستخدام الدالة المضمّنة
setMicrophoneMuted:
// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
do {
_ = try await self.cameraAvStreamManagementTrait?.update {
$0.setMicrophoneMuted(!on)
}
} catch {
// Error
}
}
تفعيل التسجيل الصوتي أو إيقافه
لتفعيل تسجيل الصوت أو إيقافه للجهاز، عدِّل السمة
recordingMicrophoneMuted
في السمة CameraAvStreamManagementTrait باستخدام الدالة المضمّنة
setRecordingMicrophoneMuted:
// 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
}
}
ضبط مستوى صوت مكبّر الصوت
لضبط مستوى صوت مكبّر الصوت للجهاز، عدِّل السمة
speakerVolumeLevel
في السمة CameraAvStreamManagementTrait باستخدام الدالة المضمّنة
setSpeakerVolumeLevel:
// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setSpeakerVolumeLevel(value)
}
} catch {
// Error
}
}
إعدادات منطقة النشاط
توفّر السمة ZoneManagement واجهة لإدارة المناطق المخصّصة التي تهمّك (مناطق النشاط) على أجهزة الكاميرا وأجراس الباب.
تُستخدَم هذه المناطق لفلترة رصد الأحداث (مثل حركة الأشخاص أو المركبات) في مناطق محدّدة ضمن مجال رؤية الجهاز.
يتم ضبط مناطق النشاط من قِبل المستخدم داخل تطبيق شريك، ما يتيح له رسم مناطق فوق مساحات محدّدة في مجال رؤية الكاميرا. بعد ذلك، يتم تحويل هذه المناطق التي يحدّدها المستخدم إلى البُنى المستخدَمة في هذه السمة. لمزيد من المعلومات حول طريقة عمل "مناطق النشاط"، يُرجى الاطّلاع على مقالة إعداد "مناطق النشاط" واستخدامها.
يتم عادةً تحديد مناطق النشاط باستخدام إحداثيات ديكارتية ثنائية الأبعاد.
توفّر السمة
TwoDCartesianVertexStruct للرؤوس و
TwoDCartesianZoneStruct
لتعريف المنطقة (الاسم والرؤوس واللون والاستخدام).
التحقّق من مناطق النشاط
لعرض مناطق النشاط، ضَع علامة في المربّع بجانب السمة
zones
في السمة ZoneManagement.
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 }
حذف منطقة نشاط
لإزالة منطقة، استخدِم الأمر
removeZone مع zoneId المحدّد.
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 do { _ = try await zoneManagementTrait.removeZone(zoneID: zoneID) } catch { // Error }
مشغّلات الأحداث الصوتية
توفّر السمة AvStreamAnalysis واجهة لإدارة مشغّلات رصد الأحداث على أجهزة الكاميرات وأجراس الأبواب. في حين أنّ المشغّلات المستندة إلى الرؤية (مثل الأشخاص أو المركبات) يمكن أن تكون خاصة بمنطقة معيّنة، تكون المشغّلات المرتبطة بالصوت عادةً إعدادات على مستوى الجهاز.
تتوفّر أنواع المشغّلات التالية لرصد الصوت باستخدام
EventTriggerTypeEnum:
| الوضع | قيمة التعداد | الوصف |
|---|---|---|
| الصوت | Sound |
رصد الصوت بشكل عام |
| شخص يتحدث | PersonTalking |
رصد الكلام |
| نباح كلب | DogBark |
يرصد أصوات الكلاب. |
| انكسار الزجاج | GlassBreak |
ترصد هذه الميزة صوت انكسار الزجاج. |
| إنذار الدخان | SmokeAlarm |
يرصد أجهزة إنذار الدخان، والتي يتم التعرّف عليها غالبًا من خلال نمط الصوت T3 (ثلاث صفارات قصيرة تليها فترة توقّف). |
| إنذار أول أكسيد الكربون | 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
استراتيجيات التسجيل المتاحة:
| الوضع | قيمة التعداد | الوصف |
|---|---|---|
| غير مفعَّلة | Disabled |
تم إيقاف التسجيل نهائيًا. يتم استخدامه بشكل أساسي من خلال الأجهزة القديمة. |
| التسجيل المتواصل | Cvr |
يتم تسجيل الفيديو على مدار الساعة طيلة أيام الأسبوع. يتطلب هذا الإجراء الاشتراك (على سبيل المثال، Google Home Premium. |
| التسجيل المستند إلى الأحداث (EBR) | Ebr |
يتم بدء التسجيل عند رصد أحداث (أشخاص أو حركة). تعتمد مدة الفيديو على مدة الحدث والاشتراك. |
| ETR (التسجيل عند بدء حدث) | Etr |
تسجيل معاينة قصيرة (لمدة 10 ثوانٍ مثلاً) يتم تشغيله عند وقوع أحداث |
| العرض المباشر | LiveView |
يتم إيقاف التسجيل، ولكن يظل بإمكان المستخدمين الوصول إلى البث المباشر. |
| الصور الثابتة | Images |
يتم تسجيل لقطات بدلاً من الفيديو عند وقوع أحداث. |
التحقّق من أوضاع التسجيل
لعرض إعدادات التسجيل الحالية، تحقَّق من سمات السمة RecordingMode:
-
supportedRecordingModes- جميع وسائل النقل المحتملة availableRecordingModes- أوضاع قابلة للاختيارselectedRecordingMode- وضع النشاط
// 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.
تفعيل ميزة "الرؤية الليلية" أو إيقافها
لتفعيل ميزة "الرؤية الليلية" أو إيقافها للكاميرا، استخدِم TriStateAutoEnum لتعديل السمة nightVision الخاصة بالسمة CameraAvStreamManagementTrait باستخدام الدالة setNightVision المضمّنة:
// 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
للسمة CameraAvStreamManagementTrait باستخدام الدالة المضمّنة
setStatusLightBrightness:
// 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 على واجهة مستخدم التطبيق وطريقة تنفيذ الكاميرا. على مستوى أساسي جدًا، لضبط إطار العرض لفيديو الكاميرا، عدِّل السمة viewport الخاصة بالسمة CameraAvStreamManagementTrait باستخدام 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).
لتفعيل الإحصاءات لجهاز، اضبط السمة
analyticsEnabled)
لـ
ExtendedGeneralDiagnosticsTrait
على true. عند ضبط analyticsEnabled، يتم تلقائيًا ضبط موقع آخر، وهو logUploadEnabled، على true، ما يتيح تحميل ملفات سجلّات الإحصاءات إلى سحابة Google Home.
// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(true)
}
// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(false)
}
إعدادات النقل والتسجيل
يتناول هذا القسم الإعدادات المتعلّقة بجودة بث الكاميرا وتفعيل الأحداث. تتم إدارة هذه الإعدادات من خلال السمة
PushAvStreamTransport.
قراءة إعدادات النقل
يوضّح هذا القسم كيفية استرداد الإعدادات الحالية من كاميرا أو جرس باب. يتم استرداد السمة PushAvStreamTransport، والعثور على اتصال معيّن مستخدَم للتسجيل، ثم استخراج القيم الحالية لجودة النطاق الترددي وحساسية أجهزة الاستشعار لتشغيل الكاميرا وأقصى مدة للحدث.
// Assuming access to // var pushAvStreamTransportTrait: Google.PushAvStreamTransportTrait let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations // Locate the connection designated for recording let recordingConnection = connections.first { connection in guard let transportOptions = connection.transportOptions else { return false } return transportOptions.streamUsage == .recording } let options = recordingConnection?.transportOptions // 1. Bandwidth Quality (Video Stream ID) let videoStreamId = options?.videoStreamID // 2. Wake-up Sensitivity (Motion Sensitivity) let wakeUpSensitivity = options?.triggerOptions.motionSensitivity // 3. Max Event Length (Motion Trigger Time Control) let maxEventLength = options?.triggerOptions.motionTimeControl?.maxDuration
تعديل إعدادات وسائل النقل
يوضّح هذا القسم كيفية تغيير إعدادات النقل.
تنشئ هذه العملية TransportOptionsStruct جديدًا يحتوي على القيم الجديدة، ثم تستخدم الأمر modifyPushTransport لإعادة إرسال هذه الإعدادات المعدَّلة إلى الجهاز، وتطبيقها على اتصال التسجيل الذي تم العثور عليه في الخطوة السابقة.
لتعديل هذه الإعدادات، استخدِم الأمر
modifyPushTransport
مع TransportOptionsStruct.
// Example: Updating to Max Quality and 30s duration let currentOptions = recordingConnection!.transportOptions! let newOptions = Google.PushAvStreamTransportTrait.TransportOptionsStruct( streamUsage: .recording, videoStreamID: 2, // Max Quality tlsEndpointID: currentOptions.tlsEndpointID, url: currentOptions.url, triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct( triggerType: .motion, motionSensitivity: 5, // Medium motionTimeControl: Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct( initialDuration: currentOptions.triggerOptions.motionTimeControl?.initialDuration ?? 10, augmentationDuration: currentOptions.triggerOptions.motionTimeControl?.augmentationDuration ?? 5, maxDuration: 30, blindDuration: currentOptions.triggerOptions.motionTimeControl?.blindDuration ?? 0 ) ), ingestMethod: currentOptions.ingestMethod, containerOptions: currentOptions.containerOptions ) try await pushAvStreamTransportTrait.modifyPushTransport( connectionID: recordingConnection!.connectionID, transportOptions: newOptions )
تحديد جودة معدّل نقل البيانات
تتوافق السمة videoStreamId في TransportOptionsStruct مع إعدادات معيّنة لبث الفيديو.
للحصول على بث الفيديو المتوافق، يُرجى الرجوع إلى السمة allocatedVideoStreams، وهي قائمة VideoStreamStructs.
من السمة CameraAvStreamManagement للجهاز
ضبط حساسية أجهزة الاستشعار لتشغيل الكاميرا
تتوافق السمة motionSensitivity الخاصة بالعنصر TransportTriggerOptionsStruct مع القيم التالية:
| التصنيف | القيمة (UInt8) |
|---|---|
| منخفض | 1 |
| متوسط | 5 |
| عالٍ | 10 |
تعديل المدة القصوى للأحداث
تتطابق السمة maxDuration
الخاصة بالنوع TransportMotionTriggerTimeControlStruct
مع المدد التالية UInt32 (بالثواني):
- 10 أو 15 أو 30 أو 60 أو 120 أو 180
إعدادات الجرس
يمكن التحكّم في إعدادات رنين جرس الباب المختلفة من خلال واجهات برمجة التطبيقات Home.
تغيير صوت الجرس
لتغيير صوت رنين جرس الباب، عليك أولاً الحصول على قائمة بأصوات الرنين المثبّتة على الجهاز باستخدام السمة installedChimeSounds الخاصة بسمة ChimeTrait:
doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
return chimeSound.chimeID, chimeSound.name
}
بعد ذلك، عدِّل السمة
selectedChime
للسمة ChimeTrait باستخدام الدالة المضمّنة setSelectedChime:
func setDoorbellChime(chimeID: UInt8) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setSelectedChime(chimeID)
}
} catch {
// Error
}
}
استخدام جرس خارجي
يمكن ضبط جرس الباب لاستخدام جرس خارجي، مثل جرس ميكانيكي مثبّت داخل المنزل. يجب ضبط هذا الإعداد أثناء عملية تثبيت جرس الباب لتجنُّب أي تلف محتمل في الجرس الخارجي.
لتحديد نوع الجرس الخارجي المثبَّت، استخدِم
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 APIs. إذا كان الجرس الخارجي يتيح ضبط مدة الرنين، قد يريد المستخدم ضبط هذه المدة.
تعتمد القيمة المحدّدة هنا على مواصفات الجرس الخارجي نفسه، وعلى مدة الرنين الموصى بها.
لتغيير مدة الرنين الخارجي، عدِّل السمة
externalChimeDurationSeconds
في السمة ChimeTrait باستخدام الدالة المضمّنة
setExternalChimeDurationSeconds:
// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setExternalChimeDuration(value)
}
} catch {
// Error
}
}
تفعيل مظهر رنين
قد تتضمّن بعض أجراس الباب نغمات لا تتوفّر للمستخدمين إلا لفترة محدودة. على سبيل المثال، أصوات رنين خاصة بالعطلات. وتُعرف هذه الأصوات باسم "مواضيع الرنين".
لمعرفة مواضيع الرنين المتاحة لمستخدم معيّن، أنشئ فلترًا زمنيًا واستخدِمه لفلترة نتائج الأمر getAvailableThemes من السمة ChimeThemes. يعرض هذا الأمر قائمة بالمظاهر المتاحة، بما في ذلك أسماء المظاهر.
يوضّح المثال التالي كيفية فلترة القائمة.
يُعد المظهر نشطًا إذا كان الوقت الحالي ضمن وقتَي البدء والانتهاء (قيمتَي 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 <= currentDateTime
&& chimeTheme.endTimeSeconds ?? UInt64.max >= currentDateTime
{
self.chimeThemeSettings.append(chimeTheme.name)
}
}
}
بعد الحصول على اسم المظهر الذي تريده، مثل Christmas، يمكنك اختياره باستخدام الدالة setSelectedTimeboxedThemeName() في السمة ChimeThemes ChimeThemes.
private func setChimeTheme(to value: String) async throws {
_ = try await chimeThemeTrait.update {
$0.setSelectedTimeboxedThemeName(value)
}
}
إعدادات الإبلاغ بقدوم زوّار
يمكنك طلب إعدادات ميزة "الإبلاغ بقدوم زوّار" وإدارتها لأجراس الباب باستخدام السمة
VisitorAnnouncement
في واجهات برمجة التطبيقات Home APIs. تتحكّم هذه السمة في ما إذا كان يتم الإبلاغ عن قدوم زائر على مكبّرات الصوت أو شاشات العرض الذكية من Google عندما يقرع أحدهم جرس الباب.
يوضّح المثال التالي كيفية التحقّق مما إذا كانت ميزة "الإبلاغ بقدوم زوّار" مفعّلة وكيفية تعديل هذا الإعداد:
let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled let value: Bool _ = try await self.visitorAnnouncementTrait?.update { $0.setVisitorAnnouncementsEnabled(value) }