يتم تنفيذ نوع الجهاز "جرس الباب" باستخدام ثلاث سمات:
PushAvStreamTransport،
التي تتعامل مع نقل بث الصوت والفيديو باستخدام بروتوكولات مستندة إلى الدفع،
WebRtcLiveView،
التي تتيح التحكّم في البث المباشر والتواصل ثنائي الاتجاه،
CameraSnapshot،
التي توفّر لقطات معاينة مخزّنة مؤقتًا وعمليات التقاط لقطات مباشرة.
يجب دائمًا التحقّق من توفّر السمات والأوامر لجهاز معيّن قبل استخدام أي ميزات أو محاولة تعديل السمات. لمزيد من المعلومات، يمكنك الاطّلاع على التحكّم في الأجهزة على Android.
| نوع الجهاز في Home APIs | السمات | نموذج تطبيق Kotlin | حالة الاستخدام |
|---|---|---|---|
|
جرس الباب
جهاز يتم تشغيله بواسطة زر خارج الباب ويصدر إشارة مسموعة و/أو مرئية، ويُستخدم لطلب انتباه شخص موجود على الجانب الآخر من الباب. قد تتضمّن أجراس الباب ميزات مثل البث المباشر الذي يسهل الوصول إليه أو التحدّث ثنائي الاتجاه أو رصد الأحداث. |
السمات المطلوبة google PushAvStreamTransport google WebRtcLiveView |
جرس الباب |
الحصول على معلومات أساسية عن جهاز
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
يتضمّن السمة BasicInformation معلومات، مثل اسم المورّد ومعرّف المورّد ومعرّف المنتج واسم المنتج (يتضمّن معلومات الطراز) وإصدار البرنامج للجهاز:
// Get device basic information. All general information traits are on the RootNodeDevice type. device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation -> println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}") println("productName ${basicInformation.productName}") println("softwareVersion ${basicInformation.softwareVersion}") }
الحصول على الرقم التسلسلي
للحصول على الرقم التسلسلي للجهاز، استخدِم الأمر
GetSerialNumber الخاص بالسمة
ExtendedBasicInformation.
يعرض المثال حفظ الرقم التسلسلي في متغيّر باسم serialNumber:
val basicInfo: ExtendedBasicInformation = device.getTrait(ExtendedBasicInformation) val serialNumber = basicInfo.getSerialNumber().serialNumber
الردود السريعة
تتيح ميزة "الردود السريعة" للمستخدم إمكانية إرسال رسالة محدّدة مسبقًا إلى جهاز جرس الباب.
تتوفّر هذه الميزة على أجهزة جرس الباب فقط. تتوفّر قائمة بالرسائل المحدّدة مسبقًا لتطبيق الشريك، ويمكن أن يعرضها التطبيق للمستخدم ليختار من بينها. الرسائل المحدّدة مسبقًا غير قابلة للتعديل من قِبل المستخدم.
يتم تنفيذ ميزة "الردود السريعة" من خلال السمة
PresetMessage.
تشغيل رسالة معدّة مسبقًا
لتشغيل رسالة مُعدّة مسبقًا، استدعِ طريقة
playPresetMessage
، وأدخِل إحدى قيم السلسلة التي تم العثور عليها في السمة
availablePhraseTypes.
import com.google.home.HomeDevice
import com.google.home.HomeException
import com.google.home.google.GoogleDoorbellDevice
import com.google.home.google.PresetMessage
import kotlinx.coroutines.flow.first
suspend fun playDoorbellPresetMessage(device: HomeDevice, phraseTypeString: String) {
try {
// 1. Retrieve the first snapshot of the doorbell device type
val doorbellDevice = device.type(GoogleDoorbellDevice).first()
// 2. Extract the PresetMessage trait
val presetMessageTrait = doorbellDevice.trait(PresetMessage)
if (presetMessageTrait == null) {
println("PresetMessage trait is not supported on this doorbell device.")
return
}
// 3. (Optional) Check available phrase types supported by the device
val availablePhrases = presetMessageTrait.availablePhraseTypes
if (availablePhrases != null) {
val phraseTypesList = availablePhrases.map { it.phraseType }
println("Supported quick response phrases: $phraseTypesList")
}
// 4. Send the playPresetMessage command to the doorbell
presetMessageTrait.playPresetMessage(phraseType = phraseTypeString)
println("Preset message command sent successfully.")
} catch (e: HomeException) {
println("Home API error occurred: ${e.message}")
} catch (e: Exception) {
println("Unexpected failure: ${e.message}")
}
}
ضبط اللغة المحكية
اضبط اللغة المنطوقة النشطة لجهاز على لغة محلية معيّنة
(مثلاً "en_US") باستخدام طريقة setActiveLocale من السمة
LocalizationConfiguration.
import java.util.Locale // Convert underscore format (en_US) to Java Locale fun String.toLocale(): Locale = Locale.forLanguageTag(this.replace('_', '-')) // Setting the active language val trait: LocalizationConfiguration = device.getTrait(LocalizationConfiguration) val selectedLocale = "en_US" // Target locale string trait.update { setActiveLocale(selectedLocale) }
الحصول على آخر وقت تم فيه حفظ جهة اتصال الجهاز على السحابة الإلكترونية
للعثور على آخر مرة كان الجهاز على اتصال بالسحابة الإلكترونية، استخدِم السمة lastContactTimestamp الخاصة بالسمة ExtendedGeneralDiagnostics:
fun getLastContactTimeStamp(trait: ExtendedGeneralDiagnostics): java.time.Instant { val timestamp = trait.lastContactTimestamp return Instant.ofEpochSecond(timestamp.toLong()) }
إعدادات نوع قاعدة الكاميرا
تحتوي السمة Mount على إعدادات حامل الكاميرا ومعلومات الحالة. يمكنك قراءة سمات، مثل حالة الربط ونوع الاكتشاف واسم نوع الربط. بالإضافة إلى ذلك، يمكنك استخدام السمة Mount لتجاوز الإعدادات التلقائية لنوع التحميل.
// Get the Mount trait val mountTrait: Mount = device.getTrait(Mount) // Read the current mount state and detection type val mountState = mountTrait.mountState val mountDetectionType = mountTrait.mountDetectionType // Read the current mount type name val mountTypeName = mountTrait.mountTypeName // Update the mount type override mountTrait.update { setMountTypeOverride(MountTrait.MountTypeOverrideEnum.Official) }
التحقّق من إمكانية اتصال جهاز
يتم في الواقع التحقّق من إمكانية الاتصال بجهاز على مستوى نوع الجهاز، لأنّ بعض الأجهزة تتوافق مع أنواع أجهزة متعددة. الحالة التي يتم عرضها هي مزيج من حالات الاتصال لجميع السمات على هذا الجهاز.
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Androidval doorbellConnectivity = doorbellDevice.metadata.sourceConnectivity.connectivityState
قد يتم رصد حالة PARTIALLY_ONLINE في حال
تضمين أنواع أجهزة مختلفة عند عدم توفّر اتصال بالإنترنت.
قد تظل سمات Matter العادية متاحة على الإنترنت بسبب التوجيه المحلي، ولكن ستكون السمات المستندة إلى السحابة الإلكترونية غير متاحة.
الحصول على عنوان IP للجهاز
للعثور على عنوان IP الخاص بالجهاز، استخدِم السمة networkInterfaces الخاصة بالسمة GeneralDiagnostics. يتم عرض العناوين على شكل مصفوفات بايت، ويمكنك تنسيقها لتصبح سلاسل IPv4 أو IPv6 عادية:
val ipAddresses =
trait.networkInterfaces?.flatMap { networkInterface ->
(networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
try {
java.net.InetAddress.getByAddress(bytes).hostAddress
} catch (e: java.net.UnknownHostException) {
null
}
}
} ?: emptyList()
بدء بث مباشر
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
لبدء بث مباشر، أرسِل سلسلة Session Description Protocol (SDP) إلى طريقة startLiveView() في السمة WebRtcLiveView، والتي تعرض WebRtcLiveViewTrait.StartLiveViewCommand.Response يحتوي على ثلاث قيم:
- تمثّل هذه السمة وصف الجلسة (SDP).
- مدة الجلسة بالثواني
- معرّف الجلسة الذي يمكن استخدامه لتمديد الجلسة أو إنهاءها
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) { return cameraDevice.type(GoogleDoorbellDevice).trait(WebRtcLiveView).first { it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE } } // Start the live view suspend fun startCameraStream(trait: WebRtcLiveView, offerSdp: String) { val response = trait.startLiveView(offerSdp) // Response contains three fields (see below) return response } ... // This is used to manage the WebRTC connection val peerConnection: RTCPeerConnection = ... ... val startResponse = startCameraStream(sdp) val answerSdp = startResponse?.answerSdp val sessionDuration = startResponse?.liveSessionDurationSeconds val mediaSessionId = startResponse?.mediaSessionId peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER, answerSdp)
تمديد مدة بث مباشر
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
تتضمّن أحداث البث المباشر مدة محددة مسبقًا تنتهي بعدها. لتمديد مدة بث نشط، أرسِل طلب تمديد باستخدام طريقة WebRtcLiveView.extendLiveView():
// Assuming camera stream has just been started suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) { delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000) val response = trait.extendLiveView(mediaSessionId) // returns how long the session will be live for return response.liveSessionDurationSeconds }
بدء ميزة TalkBack وإيقافها
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
لبدء ميزة Talkback، استدعِ طريقة startTalkback() الخاصة بسمة
WebRtcLiveView. لإيقاف التسجيل، استخدِم
stopTalkback().
// Make sure camera stream is on suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) { if(isOn) { trait.startTalkback(mediaSessionId) } else { trait.stopTalkback(mediaSessionId) } }
تفعيل ميزة التسجيل وإيقافها
لتفعيل إمكانية التسجيل بالكاميرا، مرِّر
TransportStatusEnum.Active
إلى طريقة
PushAvStreamTransport
في السمة
setTransportStatus(). لإيقاف إمكانية التسجيل، مرِّر القيمة
TransportStatusEnum.Inactive.
في المثال التالي، نضمّن هذه الاستدعاءات في استدعاء واحد يستخدم Boolean لتبديل إمكانية التسجيل:
// Start or stop recording for all connections. suspend fun setCameraRecording(trait: PushAvStreamTransport, isOn: Boolean) { if(isOn) { trait.setTransportStatus(TransportStatusEnum.Active) } else { trait.setTransportStatus(TransportStatusEnum.Inactive) } }
إنّ تفعيل ميزة التسجيل بالكاميرا أو إيقافها هو نفسه تشغيل فيديو الكاميرا أو إيقافه. وعندما يكون فيديو الكاميرا مفعّلاً، يتم التسجيل (لأغراض الأحداث والمقاطع ذات الصلة).
عندما تكون إمكانية التسجيل غير مفعَّلة (يكون فيديو الكاميرا متوقفًا):
- سيظل بإمكان الكاميرا عرض الحالة "متصل" وفقًا
connectivityStateلنوع الجهاز. - لا يمكن الوصول إلى البث المباشر، ولا ترصد الكاميرا أي أحداث على السحابة الإلكترونية.
التحقّق من تفعيل إمكانية التسجيل
لتحديد ما إذا كانت إمكانية تسجيل الكاميرا مفعَّلة، تحقَّق مما إذا كان أي من عمليات الربط نشطًا. يحدّد المثال التالي دالتَين لإجراء ذلك:
// Get the on/off state suspend fun onOffState(pushAvStreamTransport: PushAvStreamTransport) { return pushAvStreamTransport .currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false } // Check if the camera's recording capability is enabled fun PushAvStreamTransport.recordModeActive(): Boolean { return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false }
هناك طريقة أخرى للتحقّق وهي استخدام الدالة findTransport() مع دالة منطقية:
// Fetch the current connections suspend fun queryRecordModeState(trait: PushAvStreamTransport) { return trait.findTransport().let { it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active } }
استرداد لقطات الكاميرا
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
استخدِم السمة CameraSnapshot لاسترداد لقطات صور ثابتة من الكاميرا.
تكون هذه اللقطات مفيدة في عدة سيناريوهات:
- كمربّع نائب في واجهة المستخدم أثناء تحميل بث مباشر باستخدام WebRTC
- كصورة معاينة ثابتة يتم ترقيتها إلى بث مباشر عند تفاعل المستخدم معها
- كلوحة خلفية لرسم مناطق الأنشطة المخصّصة وضبطها
تقدّم السمة CameraSnapshot طريقتَين لجلب اللقطات، وذلك حسب ما إذا كنت بحاجة إلى لقطة مخزّنة مؤقتًا لعرضها بسرعة أو لقطة مباشرة عند الطلب.
الحصول على لقطة معاينة مخزّنة مؤقتًا
لقطة المعاينة هي صورة مخزّنة مؤقتًا يمكن لحزمة SDK استردادها بدون تنشيط الكاميرا. هذه هي أسرع طريقة لجلب صورة ثابتة، وهي مثالية لصفحات النظرة العامة للكاميرا أو شبكات لوحات البيانات.
للحصول على لقطة المعاينة، اقرأ سمة السمة preview_image_url:
// Get a flow of the CameraSnapshot trait val cameraSnapshotFlow: Flow<CameraSnapshot?> = cameraDevice .type(GoogleCameraDevice) .trait(CameraSnapshot) // Get the current trait state val cameraSnapshot = cameraSnapshotFlow.firstOrNull() if (cameraSnapshot != null) { val previewImageUrl = cameraSnapshot.previewImageUrl // Load the preview image from the URL } else { // CameraSnapshot trait not supported on this device }
استنادًا إلى إعدادات الكاميرا ونشاطها، يشير عنوان URL الخاص بالمعاينة إلى صورة مخزّنة مؤقتًا تم إنشاؤها من لقطات فيديو حديثة (أول إطار رئيسي في أحدث جزء من الفيديو) أو إلى لقطة يتم تحميلها بشكل دوري بواسطة الكاميرا.
للإشارة إلى مدى حداثة الصورة، تضمّن سحابة Google Home عنوان X-Home-Image-Captured-At في صورة JPEG/PNG المعروضة، ويكون العنوان منسّقًا حسب التوقيت العالمي المتفق عليه (UTC). يمكنك تحليل هذا العنوان من جهة العميل لعرض عمر اللقطة في أحد التطبيقات.
الحصول على لقطة مباشرة عند الطلب
بالنسبة إلى رحلات المستخدمين التي تتطلّب عرضًا مباشرًا حاليًا من الكاميرا، مثل إعداد "مناطق النشاط"، يمكنك طلب لقطة مباشرة. يؤدي تشغيل اللقطة المباشرة إلى تنبيه الكاميرا والتقاط إطار جديد وتحميله إلى السحابة الإلكترونية.
لطلب لقطة مباشرة، استخدِم الأمر getLiveSnapshot():
try { val response = cameraSnapshot.getLiveSnapshot() val snapshotUrl = response.snapshotUrl // Load the live snapshot image from the URL } catch (e: Exception) { Log.e("CameraSnapshot", "Failed to get live snapshot: ${e.message}") }
المصادقة على طلبات اللقطات
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
تشير جميع عناوين URL الخاصة باللقطات إلى وسائط آمنة وتتطلّب رمز OAuth 2.0 المميز لنطاق Home APIs v2. لتنزيل الصور وعرضها، يجب إدخال رمز OAuth المميز كرمز حامل في رأس Authorization لطلب HTTP.
يوضّح المثال التالي كيفية ضبط طلب شبكة آمن لتنزيل لقطة:
import android.graphics.Bitmap import android.graphics.BitmapFactory import java.io.IOException import java.net.HttpURLConnection import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext /** * Downloads a snapshot from a URL using an OAuth access token. */ suspend fun loadSnapshotImage(urlString: String, oauthToken: String): Bitmap? = withContext(Dispatchers.IO) { var connection: HttpURLConnection? = null try { val url = URL(urlString) connection = url.openConnection() as HttpURLConnection // 1. Configure the HTTP GET request with the Bearer token connection.setRequestProperty("Authorization", "Bearer $oauthToken") // 2. Fetch the image data if (connection.responseCode == HttpURLConnection.HTTP_OK) { connection.inputStream.use { inputStream -> BitmapFactory.decodeStream(inputStream) } } else { null } } catch (e: IOException) { e.printStackTrace() null } finally { connection?.disconnect() } }
إدارة البث المباشر
يُعدّ تعديل جودة البث المباشر مفيدًا لتحسين استخدام معدل نقل البيانات استنادًا إلى سياق المشاهدة لدى العميل (على سبيل المثال، التبديل إلى دقة أقل عند عرض مربّع معاينة أصغر أو عرض على شكل مربّعات أو وضع "نافذة ضمن النافذة").
يؤدي تغيير الجودة بشكل ديناميكي باستخدام السمة
WebRtcLiveView
إلى إدارة دقة جلسة البث المباشر النشطة
على برنامج معيّن. وهي تختلف عن ضبط إعدادات استخدام النطاق الترددي على مستوى الجهاز مباشرةً، ما سيؤثر في جميع المشاهدين المتزامنين وجودة تسجيلات الفيديو السابقة المحفوظة على السحابة الإلكترونية.
يوضّح المثال التالي كيفية استرداد جودة البث المباشر وتعديلها على جهاز:
استرداد خيارات الجودة المتوافقة: الحصول على درجات الدقة المتاحة للبث المتوافق مع الجهاز يطلب الرمز سمة
supportedQualityHintsالخاصة بـWebRtcLiveViewفي مسار نوع الجهاز، ويعرض الجودات المتوافقة كـStateFlowيتضمّن قائمة بقيمQualityHint(مثلQUALITY_HINT_SDأوQUALITY_HINT_HDأوQUALITY_HINT_FHDأوQUALITY_HINT_QHDأوQUALITY_HINT_UHD).تغيير جودة البث المباشر: تطبيق
QualityHintمحدّد لتغيير دقة البث المباشر النشط (على سبيل المثال، التبديل من الدقة العادية إلى الدقة العالية) تعمل الدالةchangeQualityعلى حل سمة البث المباشر للجهاز وتستدعي الدالةchangeLiveViewQualityمعmediaSessionIdالنشط وإعداداتQualityHintالمحدّدة.
// Assuming you have a HomeDevice instance 'device' val availableQualityHints: StateFlow<List> = device.type(GoogleDoorbellDevice) .trait(WebRtcLiveView) .map { trait -> trait?.supportedQualityHints ?: emptyList() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) // Assuming you have a HomeDevice instance 'device' suspend fun changeQuality(mediaSessionId: String, qualityHint: QualityHint) { // Get the trait from the device val trait = device.type(GoogleDoorbellDevice).trait(WebRtcLiveView).first() ?: return try { trait.changeLiveViewQuality(mediaSessionId, qualityHint) } catch (e: Exception) { // Handle error } }
إعدادات البطارية
يمكن التحكّم في إعدادات البطارية المختلفة من خلال واجهات برمجة التطبيقات لمنزل 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" } ]
// The index parameter must be within the UByte range (0-255). suspend fun setEnergyBalance(trait: EnergyPreference, index: Int) { trait.update { setCurrentEnergyBalance(index.toUByte()) } } // Setting the battery usage to more recording ie performance setEnergyBalance(energyPreference, 2)
تفعيل ميزة "توفير شحن البطارية" تلقائيًا
لضبط هذه الميزة، عدِّل السمة
currentLowPowerModeSensitivity
لسمة
EnergyPreference. تستخدم هذه السمة فهرسًا لاختيار مستوى حساسية، حيث يمثّل 0 عادةً Disabled، ويمثّل 1 Enabled أو Automatic.
suspend fun setAutomaticBatterySaver(enable: Boolean, trait: EnergyPreference) { // 0 is Disabled, 1 is Enabled val value = if (enable) 1.toUByte() else 0.toUByte() trait.update { setCurrentLowPowerModeSensitivity(value) } }
الحصول على حالة شحن البطارية
للحصول على حالة الشحن الحالية للجهاز (قيد الشحن أو مشحون بالكامل أو لا يتم شحنه)، استخدِم السمة batChargeState الخاصة بالسمة PowerSource.
// Get the battery charging state val batteryChargeState = powerSource.batChargeState when (batteryChargeState) { PowerSourceTrait.BatChargeStateEnum.IsCharging -> "Charging" PowerSourceTrait.BatChargeStateEnum.IsAtFullCharge -> "Full" PowerSourceTrait.BatChargeStateEnum.IsNotCharging -> "Not Charging" else -> "Unknown" }
الحصول على مستوى البطارية
للحصول على مستوى البطارية الحالي، استخدِم السمة
batChargeLevel
للسمة
PowerSource. يكون المستوى إما OK أو Warning (منخفض) أو Critical.
// Get the battery charge level val batteryLevel = powerSourceTrait.batChargeLevel when (batteryLevel) { PowerSourceTrait.BatChargeLevelEnum.OK -> "OK" PowerSourceTrait.BatChargeLevelEnum.Warning -> "Warning" PowerSourceTrait.BatChargeLevelEnum.Critical -> "Critical" else -> "Unknown" }
الحصول على مصدر الطاقة
لتحديد مصدر الطاقة الذي يستخدمه الجهاز، استخدِم السمتَين BatPresent وwiredPresent ضمن السمة PowerSource.
val trait: PowerSource val isWired = trait.wiredPresent val hasBattery = trait.batPresent
التحقّق مما إذا كان يجب استبدال البطارية
تشير السمة batReplaceability إلى ما إذا كانت البطارية غير قابلة للاستبدال أو يمكن للمستخدم استبدالها أو يمكن استبدالها في المصنع.
تخبرك السمة
batReplacementNeeded
في السمة
PowerSource
ما إذا كانت البطارية بحاجة إلى الاستبدال.
// Get the battery replacement status val batteryStatus = powerSourceTrait.batReplacementNeeded if (batteryStatus) { println("Replace the battery.") }
عندما تكون البطارية قابلة للاستبدال من قِبل المستخدم، يقدّم
batReplacementDescription
وصفًا للبطارية، بما في ذلك معلومات مثل عامل الشكل والتركيب الكيميائي والشركة المصنّعة المفضّلة.
إعدادات الصوت
يمكن التحكّم في إعدادات الصوت المختلفة من خلال واجهات برمجة التطبيقات Home.
تفعيل الميكروفون أو إيقافه
لتفعيل ميكروفون الجهاز أو إيقافه، عدِّل السمة
microphoneMuted
الخاصة بسمة CameraAvStreamManagement باستخدام دالة
setMicrophoneMuted Kotlin المضمّنة:
// Turn the device's microphone on or off suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) { trait.update { setMicrophoneMuted(disableMicrophone) } }
تفعيل تسجيل الصوت أو إيقافه
لتفعيل تسجيل الصوت أو إيقافه على الجهاز، عدِّل السمة
recordingMicrophoneMuted
لسمة CameraAvStreamManagement باستخدام دالة
setRecordingMicrophoneMuted Kotlin المضمّنة:
// Turn audio recording on or off for the device suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) { trait.update { setRecordingMicrophoneMuted(disableAudioRecording) } }
ضبط مستوى صوت المكبّر
لضبط مستوى صوت مكبّر الصوت للجهاز، عدِّل السمة
speakerVolumeLevel
في السمة CameraAvStreamManagement باستخدام دالة
setSpeakerVolumeLevel Kotlin المضمّنة:
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
إعدادات منطقة النشاط
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
توفّر السمة ZoneManagement واجهة لإدارة المناطق المخصّصة التي تهمّك (مناطق النشاط) على أجهزة الكاميرا وأجراس الباب.
تُستخدَم هذه المناطق لفلترة رصد الأحداث (مثل حركة الأشخاص أو المركبات) في مناطق محدّدة ضمن مجال رؤية الجهاز.
يتم ضبط مناطق النشاط من قِبل المستخدم داخل تطبيق شريك، ما يتيح له رسم مناطق فوق مساحات معيّنة في مجال رؤية الكاميرا. بعد ذلك، يتم تحويل هذه المناطق التي يحدّدها المستخدم إلى البِنى التي تستخدمها هذه السمة. لمزيد من المعلومات حول طريقة عمل مناطق النشاط، يُرجى الاطّلاع على مقالة إعداد مناطق النشاط واستخدامها.
يتم عادةً تحديد مناطق النشاط باستخدام إحداثيات ديكارتية ثنائية الأبعاد.
توفّر السمة TwoDCartesianVertexStruct للرؤوس وTwoDCartesianZoneStruct لتعريف المنطقة (الاسم والرؤوس واللون والاستخدام).
التحقّق من مناطق النشاط
لعرض مناطق النشاط، تحقَّق من السمة
zones
في السمة ZoneManagement.
// 1. Obtain the trait flow from the device private val zoneManagementFlow: Flow= device.type(CAMERA_TYPE).flatMapLatest { it.trait(ZoneManagement) } // 2. Map the flow to the list of zone structures val activityZones: Flow<List<ZoneManagementTrait.ZoneInformationStruct>> = zoneManagementFlow.map { trait -> trait.zones ?: emptyList() }
إضافة منطقة نشاط
لإنشاء منطقة جديدة، استخدِم الأمر
createTwoDCartesianZone. يستخدِم هذا الأمر TwoDCartesianZoneStruct،
الذي يحدّد اسم المنطقة ورؤوسها ولونها واستخدامها.
يوضّح المثال التالي كيفية إنشاء منطقة باسم "الشرفة الأمامية" بأربعة رؤوس، ولونها وردي داكن (#F439A0)، وتُستخدم لرصد الحركة.
import com.google.home.google.ZoneManagement import com.google.home.google.ZoneManagementTrait import com.google.home.matter.serialization.OptionalValue /** * Creates a custom activity zone named "Front Porch" with a salmon color * configured for motion detection. */ suspend fun createFrontPorchZone(zoneManagement: ZoneManagement) { // 1. Define the vertices for the zone (2D Cartesian coordinates) // Values are typically scaled to a maximum defined by the device's twoDCartesianMax attribute. val vertices = listOf( ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260u, y = 422u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049u, y = 0u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 0u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 950u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630u, y = 1349u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880u, y = 2048u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0u, y = 2048u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638u, y = 1090u) ) // 2. Define the zone structure val newZone = ZoneManagementTrait.TwoDCartesianZoneStruct( name = "Front Porch", vertices = vertices, // Usage defines what the zone filters (for example, Motion, Person, Vehicle) use = listOf(ZoneManagementTrait.ZoneUseEnum.Motion), // Color is typically a hex string (for example, Salmon/Pink) color = OptionalValue.present("#F439A0") ) try { // 3. Execute the command to add the zone to the device zoneManagement.createTwoDCartesianZone(newZone) println("Successfully created activity zone.") } catch (e: Exception) { // Handle potential HomeException or Timeout println("Failed to create activity zone: ${e.message}") } }
تعديل منطقة نشاط
لتعديل منطقة حالية، استخدِم الأمر updateTwoDCartesianZone. يتطلّب هذا الأمر zoneId وTwoDCartesianZoneStruct المعدَّل.
private suspend fun ZoneManagement.updateZone( zoneId: UShort, zone: ZoneManagementTrait.TwoDCartesianZoneStruct ) { // Execute the command to update the zone this.updateTwoDCartesianZone(zoneId = zoneId, zone = zone) }
حذف منطقة نشاط
لإزالة منطقة، استخدِم الأمر
removeZone
مع zoneId المحدّد.
private suspend fun ZoneManagement.deleteZone(zoneId: UShort) { // Execute the command to remove the zone this.removeZone(zoneId = zoneId) }
مشغّلات الأحداث الصوتية
توفّر السمة AvStreamAnalysis واجهة لإدارة مشغّلات رصد الأحداث على الكاميرات وأجراس الأبواب. في حين أنّ المشغّلات المستندة إلى الرؤية (مثل الأشخاص أو المركبات) يمكن أن تكون خاصة بمنطقة معيّنة، تكون المشغّلات المرتبطة بالصوت عادةً إعدادات على مستوى الجهاز.
تتوفّر أنواع المشغّلات التالية لميزة "رصد الصوت" باستخدام الرمز
EventTriggerTypeEnum:
| الوضع | قيمة التعداد | الوصف |
|---|---|---|
| الصوت | Sound |
رصد الصوت بشكل عام |
| شخص يتحدث | PersonTalking |
رصد الكلام |
| نباح الكلب | DogBark |
يرصد أصوات الكلاب. |
| انكسار الزجاج | GlassBreak |
ترصد صوت انكسار الزجاج. |
| إنذار الدخان | SmokeAlarm |
يرصد هذا الجهاز إنذارات الدخان، والتي يمكن التعرّف عليها غالبًا من خلال نمط الصوت T3 (ثلاث صفارات قصيرة تليها فترة توقّف). |
| إنذار أول أكسيد الكربون | CoAlarm |
يرصد هذا الخيار أجهزة الإنذار التي تصدر صوتًا عند رصد غاز أول أكسيد الكربون (CO)، ويتم التعرّف عليها عادةً من خلال نمط الصوت المسموع T4 (أربع صفارات قصيرة تليها فترة توقّف). |
التحقّق من حالة ميزة "رصد الصوت"
لعرض الحالة الحالية لميزة "رصد الصوت" للمستخدم، عليك التحقّق من الميزات التي يتيحها الجهاز والميزات التي يفعّلها الجهاز. السمتان المطلوب التحقّق منهما هما:
في تطوير تطبيقات Android باستخدام Kotlin Flows، يمكنك عادةً مراقبة السمة AvStreamAnalysis من HomeDevice.
// Example structure to store the data class EventTriggerAttribute(val type: EventTriggerTypeEnum, val enabled: Boolean) // 1. Obtain the trait flow from the device private val avStreamAnalysisFlow: Flow<AvStreamAnalysis> = device.traitFromType(AvStreamAnalysis, CAMERA_TYPES.first { device.has(it) }) // 2. Map the flow to a list of sound event attributes val soundEventTriggersState: Flow<List<EventTriggerAttribute>> = avStreamAnalysisFlow.map { trait -> // Get raw lists from the trait attributes val supported = trait.supportedEventTriggers ?: emptyList() val enabled = trait.enabledEventTriggers ?: emptyList() // Define sound-specific triggers to filter for val soundTypes = setOf( EventTriggerTypeEnum.Sound, EventTriggerTypeEnum.PersonTalking, EventTriggerTypeEnum.DogBark, EventTriggerTypeEnum.GlassBreak, EventTriggerTypeEnum.SmokeAlarm, EventTriggerTypeEnum.CoAlarm, ) // Filter and associate status supported .filter { soundTypes.contains(it) } .map { type -> EventTriggerAttribute( type = type, enabled = enabled.contains(type) ) } }
تعديل مجموعة عوامل التشغيل المفعَّلة
لتعديل مجموعة المشغّلات المفعَّلة، استخدِم الأمر
SetOrUpdateEventDetectionTriggers،
الذي يتضمّن قائمة ببُنى EventTriggerEnablement.
private suspend fun AvStreamAnalysis.updateEventTriggers( eventTriggers: List<EventTriggerAttribute> ) { val toUpdate = eventTriggers.map { EventTriggerEnablement( eventTriggerType = it.type, enablementStatus = if (it.enabled) { EnablementStatusEnum.Enabled } else { EnablementStatusEnum.Disabled }, ) } // Execute the command on the device setOrUpdateEventDetectionTriggers(toUpdate) }
أوضاع التسجيل
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
توفّر السمة RecordingMode واجهة لإدارة سلوك تسجيل الفيديو والصور على أجهزة الكاميرا وأجراس الباب. يتيح هذا الخيار للمستخدمين الاختيار بين التسجيل المتواصل أو التسجيل المستند إلى الأحداث أو إيقاف التسجيل بالكامل (العرض المباشر فقط).
يحدّد RecordingModeEnum
استراتيجيات التسجيل المتاحة:
| الوضع | قيمة التعداد | الوصف |
|---|---|---|
| غير مفعَّلة | Disabled |
تم إيقاف التسجيل نهائيًا. يُستخدَم بشكل أساسي من قِبل الأجهزة القديمة. |
| التسجيل المتواصل | Cvr |
يتم تسجيل الفيديو على مدار الساعة طيلة أيام الأسبوع. يتطلب اشتراكًا (مثل Google Home Premium). |
| التسجيل المستند إلى الأحداث | Ebr |
يتم بدء التسجيل عند رصد أحداث (شخص أو حركة). تعتمد مدة الفيديو على مدة الحدث والاشتراك. |
| ETR (التسجيل عند بدء الحدث) | Etr |
تسجيل معاينة قصيرة (لمدة 10 ثوانٍ مثلاً) يتم تشغيله عند وقوع أحداث |
| العرض المباشر | LiveView |
يتم إيقاف التسجيل، ولكن يظل بإمكان المستخدمين الوصول إلى البث المباشر. |
| الصور الثابتة | Images |
يتم تسجيل لقطات بدلاً من الفيديو عند وقوع الأحداث. |
التحقّق من أوضاع التسجيل
لعرض إعدادات التسجيل الحالية، تحقَّق من سمات السمة RecordingMode:
-
supportedRecordingModes- جميع الأوضاع المحتملة availableRecordingModes- الأوضاع القابلة للاختيارselectedRecordingMode- الوضع النشط
// 1. Obtain the trait flow from the device private val recordingModeTraitFlow: Flow= device.traitFromType(RecordingMode, CAMERA_TYPES.first { device.has(it) }) // 2. Map the flow to recording mode options data class RecordingModeOptions( val recordingMode: RecordingModeTrait.RecordingModeEnum, val index: Int, val available: Boolean, val readableString: String, ) private val recordingModeOptions: Flow<List > = recordingModeTraitFlow.map { trait -> val supported = trait.supportedRecordingModes?.map { it.recordingMode } ?: emptyList() val available = trait.availableRecordingModes?.map { it.toInt() } ?: emptyList() supported.withIndex().map { (index, mode) -> RecordingModeOptions( recordingMode = mode, index = index, available = available.contains(index), readableString = mode.toReadableString(), ) } }
تغيير وضع التسجيل
قبل التعديل، تأكَّد من أنّ الفهرس المحدّد من السمة supportedRecordingModes
موجود في السمة availableRecordingModes.
لتعديل الوضع المحدّد، استخدِم الدالة
setSelectedRecordingMode مع تمرير فهرس الوضع الذي تم اختياره:
private suspend fun RecordingMode.updateRecordingMode(index: Int) { // Execute the command to update the selected mode this.setSelectedRecordingMode(index.toUByte()) }
إعدادات أخرى
يمكن التحكّم في إعدادات أخرى متنوعة من خلال واجهات برمجة التطبيقات Home.
تفعيل ميزة "الرؤية الليلية" أو إيقافها
لتفعيل ميزة "الرؤية الليلية" أو إيقافها للكاميرا، استخدِم TriStateAutoEnum
لتعديل السمة
nightVision
لسمة CameraAvStreamManagement باستخدام دالة setNightVision المضمّنة في Kotlin:
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
تغيير سطوع مؤشر LED للحالة
لتغيير مستوى سطوع مؤشر LED الخاص بالحالة، استخدِم
ThreeLevelAutoEnum
لتعديل السمة
statusLightBrightness
لسمة CameraAvStreamManagement باستخدام دالة
setStatusLightBrightness Kotlin المضمّنة:
// Set the LED brightness to high cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High) } // Set the LED brightness to low cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low) }
تغيير منفذ عرض الكاميرا
منطقة عرض الكاميرا هي نفسها ميزة "التكبير والقص" الموضّحة في مقالة الدعم تكبير فيديو كاميرا Nest وتحسينه.
يتم تحديد إطار العرض في ViewportStruct يحتوي على أربع قيم تُستخدَم كإحداثيات لإطار العرض. يتم تحديد الإحداثيات على النحو التالي:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
يعتمد تحديد قيم ViewportStruct على واجهة مستخدم التطبيق وتنفيذ الكاميرا. على مستوى أساسي جدًا، لضبط إطار عرض فيديو الكاميرا، عدِّل السمة viewport الخاصة بالسمة CameraAvStreamManagement باستخدام ViewportStruct، وذلك باستخدام دالة setViewport Kotlin المضمّنة:
cameraAvStreamManagement .update { setViewport( CameraAvStreamManagementTrait.ViewportStruct( x1 = horizontalRange.rangeStart.roundToInt().toUShort(), x2 = horizontalRange.rangeEnd.roundToInt().toUShort(), y1 = verticalRange.rangeStart.roundToInt().toUShort(), y2 = verticalRange.rangeEnd.roundToInt().toUShort(), ) ) }
تفعيل الإحصاءات أو إيقافها
يمكن لكل جهاز الموافقة بشكل فردي على إرسال بيانات إحصائية مفصّلة إلى سحابة Google Home (راجِع واجهات برمجة التطبيقات الخاصة بميزة "المراقبة السحابية" في Home).
لتفعيل الإحصاءات لجهاز، اضبط السمة
analyticsEnabled
للعنصر
ExtendedGeneralDiagnosticsTrait
على true. عند ضبط analyticsEnabled، يتم تلقائيًا ضبط موقع آخر، logUploadEnabled، على true، ما يتيح تحميل ملفات سجلّ الإحصاءات إلى سحابة Google Home.
// Enable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(true) } // Disable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(false) }
إعدادات النقل والتسجيل
يتناول هذا القسم الإعدادات المتعلّقة بجودة بث الكاميرا وتفعيل الأحداث. تتم إدارة هذه الإعدادات من خلال السمة
PushAvStreamTransport.
قراءة إعدادات النقل
يوضّح هذا القسم كيفية استرداد الإعدادات الحالية من كاميرا أو جرس باب. يتم استرداد السمة PushAvStreamTransport، والعثور على الاتصال المحدّد المستخدَم للتسجيل، ثم استخراج القيم الحالية لجودة معدل نقل البيانات وحساسية أجهزة الاستشعار لتشغيل الكاميرا والحد الأقصى لطول الحدث.
val trait: PushAvStreamTransport = device.getTrait(PushAvStreamTransport) val connections = trait.findTransport().transportConfigurations // Locate the connection designated for recording val recordingConnection = connections.firstOrNull { it.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording } val options = recordingConnection?.transportOptions?.getOrNull() // 1. Bandwidth Quality (Video Stream ID) val videoStreamId = options?.videoStreamId?.getOrNull() // 2. Wake-up Sensitivity (Motion Sensitivity) val wakeUpSensitivity = options?.triggerOptions?.motionSensitivity?.getOrNull() // 3. Max Event Length (Motion Trigger Time Control) val maxEventLength = options?.triggerOptions?.motionTimeControl?.getOrNull()?.maxDuration
تعديل إعدادات النقل
يوضّح هذا القسم كيفية تغيير إعدادات النقل.
تنشئ هذه الطريقة TransportOptionsStruct جديدًا يحتوي على القيم الجديدة، ثم تستخدم الأمر modifyPushTransport لإعادة إرسال هذه الإعدادات المعدَّلة إلى الجهاز، وتطبيقها على اتصال التسجيل الذي تم العثور عليه في الخطوة السابقة.
لتعديل هذه الإعدادات، استخدِم الأمر
modifyPushTransport مع TransportOptionsStruct.
val toUpdate = TransportOptionsStruct( videoStreamId = OptionalValue.present(2u), // e.g., Max Quality triggerOptions = TransportTriggerOptionsStruct( motionSensitivity = OptionalValue.present(5u), // e.g., Medium motionTimeControl = OptionalValue.present( TransportMotionTriggerTimeControlStruct(maxDuration = 30u) ) ) ) if (recordingConnection != null) { trait.modifyPushTransport( connectionId = recordingConnection.connectionId, transportOptions = toUpdate ) }
تحديد جودة معدّل نقل البيانات
تتطابق السمة videoStreamId في TransportOptionsStruct مع إعدادات معيّنة لبث الفيديو.
للحصول على بث الفيديو المتوافق، يُرجى الرجوع إلى السمة allocatedVideoStreams، وهي عبارة عن قائمة VideoStreamStructs.
من السمة CameraAvStreamManagement للجهاز
ضبط حساسية أجهزة الاستشعار لتشغيل الكاميرا
تتوافق السمة motionSensitivity الخاصة بالعنصر TransportTriggerOptionsStruct مع القيم التالية:
| التصنيف | القيمة (UByte) |
|---|---|
| منخفض | 1u |
| متوسط | 5u |
| عالٍ | 10u |
تعديل الحد الأقصى لمدة الحدث
تتوافق السمة maxDuration
للعنصر TransportMotionTriggerTimeControlStruct
مع المدد التالية (بالثواني):
- 10u أو 15u أو 30u أو 60u أو 120u أو 180u
إعدادات الجرس
يمكن التحكّم في إعدادات رنين جرس الباب المختلفة من خلال واجهات برمجة التطبيقات Home.
تغيير صوت الجرس
لتغيير صوت رنين جرس الباب، عليك أولاً الحصول على قائمة بأصوات الرنين المثبّتة على الجهاز باستخدام السمة installedChimeSounds الخاصة بسمة Chime:
// Get a list of chimes and identify the currently selected one private val doorbellChimeTraitFlow: Flow= device.traitFromType(Chime, GoogleDoorbellDevice) val chimeSounds = doorbellChimeTraitFlow.first().installedChimeSounds ?: emptyList()
بعد ذلك، عدِّل السمة
selectedChime
للسمة Chime باستخدام دالة setSelectedChime Kotlin المضمّنة:
// Set the chime using the chimeId from the installed list chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }
استخدام جرس باب خارجي
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
يمكن ضبط جرس الباب لاستخدام رنين خارجي، مثل جرس ميكانيكي مثبّت داخل المنزل. يجب ضبط هذا الإعداد أثناء عملية تركيب جرس الباب لتجنُّب أي ضرر محتمل للجرس الخارجي.
لتحديد نوع الجرس الخارجي المثبَّت، استخدِم
ExternalChimeType
لتعديل السمة
externalChime
لسمة Chime باستخدام دالة
setExternalChime Kotlin المضمّنة:
// Indicate the external chime is mechanical chime.update { setExternalChime(ChimeTrait.ExternalChimeType.Mechanical) }
تغيير مدة الجرس الخارجي
يمكن ضبط مدة رنين الجرس الخارجي بالثواني من خلال واجهات برمجة التطبيقات Home APIs. إذا كان الجرس الخارجي يتيح ضبط مدة الرنين، قد يريد المستخدم ضبط هذه المدة.
تعتمد القيمة المضبوطة هنا على مواصفات الجرس الخارجي نفسه ومدة الرنين الموصى بها.
لتغيير مدة الرنين الخارجي، عدِّل السمة
externalChimeDurationSeconds
لسمة Chime باستخدام دالة
setExternalChimeDurationSeconds Kotlin المضمّنة:
// Change the external chime duration chime.update { setExternalChimeDurationSeconds(newDuration.toUShort()) }
تفعيل مظهر رنين
تم التنفيذ في "تطبيق العيّنة" لنظام التشغيل Android
قد تتضمّن بعض أجراس الباب نغمات لا تتوفّر للمستخدمين إلا لفترة محدودة. على سبيل المثال، أجراس خاصة بالأعياد وتُعرف هذه الأغاني باسم "أغاني الرنين".
لمعرفة مظاهر الرنين المتاحة لمستخدم معيّن، أنشئ فلترًا زمنيًا
واستخدمه لفلترة نتائج الأمر
getAvailableThemes()
من السمة
ChimeThemes. يؤدي ذلك إلى عرض قائمة بالمظاهر المتاحة، بما في ذلك أسماء المظاهر.
يوضّح المثال التالي كيفية فلترة القائمة.
يُعدّ المظهر نشطًا إذا كان الوقت الحالي ضمن وقتَي البدء والانتهاء (قيمتَي startTimeSeconds وendTimeSeconds على التوالي). إذا لم يتم ضبط وقت بدء، سيتم اعتبارها نشطة منذ البداية. إذا لم يتم ضبط وقت انتهاء، سيظل نشطًا إلى أجل غير مسمى. إذا لم يتوفّر أي منهما، يكون المظهر نشطًا دائمًا.
// Get themes from the ChimeThemes trait fun List<ChimeThemesTrait.ThemeStruct>.filterTimeboxedThemes(): List<ChimeThemesTrait.ThemeStruct> { val now = timeSource.instant().epochSecond.toULong() return filter { chimeStruct: ChimeThemesTrait.ThemeStruct -> val startTime: ULong = chimeStruct.startTimeSeconds.getOrNull() ?: 0UL val endTime: ULong = chimeStruct.endTimeSeconds.getOrNull() ?: MAX_VALUE startTime <= now && now <= endTime } } val availableThemes = doorbellChimeThemesTraitFlow .first() .getAvailableThemes() .themes .filterTimeboxedThemes()
بعد الحصول على اسم المظهر الذي تريده، مثل Christmas، يمكنك اختياره باستخدام الدالة setSelectedTimeboxedThemeName() في السمة ChimeThemes:
// Select a theme using the ChimeThemes trait val themeToSelect = "Christmas" if (themeToSelect in availableThemeNames) { doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect) }
إعدادات إشعارات الزوّار
يمكنك طلب إعدادات ميزة "الإبلاغ بقدوم زوّار" وإدارتها لأجراس الباب باستخدام السمة
VisitorAnnouncement
في Home APIs. تتحكّم هذه السمة في ما إذا كان يتم الإبلاغ عن قدوم زائر على مكبّرات الصوت أو شاشات العرض الذكية من Google عندما يقرع أحدهم جرس الباب.
يوضّح المثال التالي كيفية التحقّق مما إذا كانت الإبلاغ بقدوم زوّار مفعّلة وكيفية تعديل هذا الإعداد:
// Read the current visitor announcements state val isEnabled = visitorAnnouncementTrait.visitorAnnouncementsEnabled // Toggle the visitor announcements setting visitorAnnouncementTrait.update { setVisitorAnnouncementsEnabled(true) }
إيقاف جهاز نهائيًا
لإزالة جرس باب من مبنى، اتّصِل بالرقم
device.decommissionDevice(). عند إيقاف الجهاز نهائيًا، ستظهر للمستخدم شاشة تأكيد تديرها Google تحذّره من أنّه سيتم نهائيًا حذف كل بيانات سجلّ الفيديو على مدار الساعة وسجلّ الأحداث والمقاطع ومكتبة الوجوه المألوفة في جميع أنحاء المكان.
للحصول على تعليمات مفصّلة وأمثلة على الرموز البرمجية، يُرجى الاطّلاع على إزالة جهاز.