Urządzenie typu dzwonek do drzwi jest implementowane za pomocą 2 cech:PushAvStreamTransportTrait, która obsługuje transport strumieni audio i wideo za pomocą protokołów opartych na push, orazWebRtcLiveViewTrait, która umożliwia sterowanie transmisjami na żywo i funkcją talkback.
Przed użyciem jakichkolwiek funkcji lub próbą zaktualizowania atrybutów zawsze sprawdzaj, czy urządzenie obsługuje atrybuty i polecenia. Więcej informacji znajdziesz w artykule Sterowanie urządzeniami na iOS.
| Typ urządzenia interfejsów Home API | Cechy | Przykładowa aplikacja w Swift | Przypadek użycia |
|---|---|---|---|
|
Dzwonek
Urządzenie uruchamiane przyciskiem na zewnątrz drzwi, które emituje sygnał dźwiękowy lub wizualny, używane do zwrócenia uwagi osoby znajdującej się po drugiej stronie drzwi. Dzwonki do drzwi mogą mieć funkcje transmisji na żywo z ułatwieniami dostępu, dwukierunkowego odtwarzania dźwięku lub wykrywania zdarzeń. |
Wymagane cechy google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
Dzwonek |
Uzyskiwanie podstawowych informacji o urządzeniu
Cechą BasicInformation
są informacje takie jak nazwa dostawcy, identyfikator dostawcy, identyfikator produktu,
nazwa produktu (zawiera informacje o modelu), wersja oprogramowania
i numer seryjny urządzenia:
// [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! let serialNumber = basicInfoTrait.attributes.serialNumber! // [END get_device_information]
Pobieranie najnowszej godziny kontaktu urządzenia z chmurą
Aby znaleźć ostatni czas, w którym urządzenie miało kontakt z chmurą, użyj atrybutu lastContactTimestamp cechy ExtendedGeneralDiagnostics:
if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp { self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp)) }
Sprawdzanie połączenia urządzenia
Połączenie urządzenia jest sprawdzane na poziomie typu urządzenia, ponieważ niektóre urządzenia obsługują wiele typów. Zwracany stan jest kombinacją stanów łączności wszystkich cech na tym urządzeniu.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Stan partiallyOnline może wystąpić w przypadku różnych typów urządzeń, gdy nie ma połączenia z internetem. Matter standardowe cechy mogą być nadal dostępne online ze względu na routing lokalny, ale cechy oparte na chmurze będą niedostępne.
Rozpoczynanie transmisji na żywo
Aby rozpocząć transmisję na żywo, wyślij ciąg protokołu SDP (Session Description Protocol) do metody startLiveView(offerSdp:) cechy WebRtcLiveViewTrait, która zwraca 3 wartości:
- SDP sesji.
- Czas trwania sesji w sekundach.
- Identyfikator sesji, który może służyć do przedłużenia lub zakończenia sesji.
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
}
}
Przedłużanie transmisji na żywo
Transmisje na żywo mają z góry określony czas trwania, po którym wygasają. Aby wydłużyć czas trwania aktywnego strumienia, wyślij prośbę o przedłużenie za pomocą metody 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
}
}
Włączanie i wyłączanie TalkBack
Aby uruchomić TalkBack, wywołaj metodę startTalkback(mediaSessionId:optionalArgsProvider:) cechy
WebRtcLiveViewTrait.
Aby zatrzymać, użyj 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)")
}
}
Włączanie i wyłączanie możliwości nagrywania
Aby włączyć funkcję nagrywania kamery, przekaż wartość
TransportStatusEnum.Active
do metody
PushAvStreamTransportTrait
cechy
setTransportStatus(transportStatus:optionalArgsProvider:). Aby wyłączyć możliwość nagrywania, przekaż wartość
TransportStatusEnum.Inactive.
W poniższym przykładzie umieszczamy te wywołania w jednym wywołaniu, które używa Boolean, aby przełączać możliwość nagrywania:
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
}
}
}
Włączenie lub wyłączenie nagrywania przez kamerę jest równoznaczne z włączeniem lub wyłączeniem wideo z kamery. Gdy wideo z kamery jest włączone, kamera nagrywa (na potrzeby zdarzeń i powiązanych klipów).
Gdy funkcja nagrywania jest wyłączona (wideo z kamery jest wyłączone):
- Kamera może nadal być widoczna jako online zgodnie z
connectivityStatetypu urządzenia. - Nie można uzyskać dostępu do transmisji na żywo, a kamera nie wykrywa żadnych zdarzeń w chmurze.
Sprawdzanie, czy funkcja nagrywania jest włączona
Aby sprawdzić, czy funkcja nagrywania kamery jest włączona, sprawdź, czy są aktywne jakiekolwiek połączenia. Poniższy przykład definiuje 2 funkcje, które to umożliwiają:
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
}
Ustawienia baterii
Różnymi ustawieniami baterii można sterować za pomocą interfejsów Home API.
Ustawianie preferencji wykorzystania baterii
Ustawienie bilansu energetycznego umożliwia skonfigurowanie kompromisu między czasem pracy baterii a wydajnością urządzenia. Możesz utworzyć różne profile baterii, np. „Wydłużony”, „Zrównoważony” i „Wydajność”, i przełączać się między nimi.
Ta funkcja jest wdrażana przez aktualizację atrybutu currentEnergyBalance cechy EnergyPreference. Atrybut przyjmuje liczbę całkowitą, która odpowiada konkretnemu profilowi zdefiniowanemu na liście energyBalances urządzenia (np. 0 dla EXTENDED, 1 dla BALANCED i 2 dla PERFORMANCE).
Wartość null w przypadku currentEnergyBalance oznacza, że urządzenie używa profilu niestandardowego. Jest to stan tylko do odczytu.
Poniżej znajdziesz przykład struktury, której będzie używać atrybut currentEnergyBalance, a następnie fragment kodu, który korzysta z tego atrybutu.
// 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) } }
Włączanie automatycznego oszczędzania baterii
Aby skonfigurować tę funkcję, zaktualizuj atrybut currentLowPowerModeSensitivity cechy EnergyPreference. Ten atrybut używa indeksu do wyboru poziomu wrażliwości, gdzie 0 zwykle oznacza Disabled, a 1 oznacza Enabled lub Automatic.
private func setAutoBatterySaver(to value: Bool) async throws { _ = try await energyPreferenceTrait.update { $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0) } }
Sprawdzanie stanu ładowania baterii
Aby uzyskać bieżący stan ładowania urządzenia (ładowanie, pełne naładowanie lub brak ładowania), użyj atrybutu batChargeState cechy 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" }
Sprawdzanie poziomu baterii
Aby uzyskać bieżący poziom baterii, użyj atrybutu
batChargeLevel
cechy
PowerSource. Poziom to OK, Warning (niski) lub 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" }
Uzyskiwanie źródła zasilania
Aby określić źródło zasilania urządzenia, użyj atrybutów BatPresent i wiredPresent cechy PowerSource.
if powerSourceTrait.attributes.wiredPresent ?? false { self.powerSourceType = .wired } else if powerSourceTrait.attributes.batPresent ?? false { self.powerSourceType = .battery } else { self.powerSourceType = nil }
Ustawienia dźwięku
Różnymi ustawieniami dźwięku można sterować za pomocą interfejsów Home API.
Włączanie i wyłączanie mikrofonu
Aby włączyć lub wyłączyć mikrofon urządzenia, zaktualizuj atrybut microphoneMuted
cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji 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
}
}
Włączanie i wyłączanie nagrywania dźwięku
Aby włączyć lub wyłączyć nagrywanie dźwięku na urządzeniu, zaktualizuj atrybut
recordingMicrophoneMuted
cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji
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
}
}
Dostosowywanie głośności głośnika
Aby dostosować głośność głośnika urządzenia, zaktualizuj atrybut speakerVolumeLevel cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji setSpeakerVolumeLevel:
// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setSpeakerVolumeLevel(value)
}
} catch {
// Error
}
}
Ustawienia miejsc aktywności
Cechą ZoneManagement jest interfejs do zarządzania niestandardowymi obszarami zainteresowania (miejscami aktywności) na kamerach i dzwonkach do drzwi.
Strefy te służą do filtrowania wykrywania zdarzeń (np. ruchu osoby lub pojazdu) w określonych obszarach w polu widzenia urządzenia.
Miejsca aktywności są konfigurowane przez użytkownika w aplikacji partnera. Umożliwia to wyznaczanie stref w określonych obszarach pola widzenia kamery. Zdefiniowane przez użytkownika strefy są następnie przekształcane w struktury używane przez ten atrybut. Więcej informacji o tym, jak działają miejsca aktywności, znajdziesz w artykule Konfigurowanie i używanie miejsc aktywności.
Strefy aktywności są zwykle definiowane za pomocą 2-wymiarowych współrzędnych kartezjańskich.
Cechą jest TwoDCartesianVertexStruct dla wierzchołków i TwoDCartesianZoneStruct
dla definicji strefy (nazwa, wierzchołki, kolor i użycie).
Sprawdzanie miejsc aktywności
Aby wyświetlić strefy aktywności, sprawdź atrybut zones
cechy ZoneManagement.
let zoneManagementTrait: Google.ZoneManagementTrait self.zones = zoneManagementTrait.attributes.zones ?? []
Dodawanie strefy aktywności
Aby utworzyć nową strefę, użyj polecenia createTwoDCartesianZone. To polecenie przyjmuje TwoDCartesianZoneStruct, który określa nazwę, wierzchołki, kolor i użycie strefy.
Poniższy przykład pokazuje, jak utworzyć strefę o nazwie „Front Porch” (Weranda) z 4 wierzchołkami w kolorze łososiowym (#F439A0), która będzie używana do wykrywania ruchu.
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 } }
Aktualizowanie strefy aktywności
Aby zaktualizować istniejącą strefę, użyj polecenia
updateTwoDCartesianZone. To polecenie wymaga zoneId i zaktualizowanego TwoDCartesianZoneStruct.
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 let zone: Google.ZoneManagementTrait.TwoDCartesianZoneStruct do { _ = try await zoneManagementTrait.updateTwoDCartesianZone( zoneID: zoneID, zone: zone) } catch { // Error }
Usuwanie strefy aktywności
Aby usunąć strefę, użyj polecenia removeZone z określonym argumentem zoneId.
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 do { _ = try await zoneManagementTrait.removeZone(zoneID: zoneID) } catch { // Error }
Aktywatory zdarzeń dźwiękowych
Cecha AvStreamAnalysis udostępnia interfejs do zarządzania wyzwalaczami wykrywania zdarzeń na kamerach i dzwonkach do drzwi. Wywoływanie na podstawie obrazu (np. wykrywanie osób lub pojazdów) może być związane z określonym obszarem, ale wywoływanie na podstawie dźwięku jest zwykle konfigurowane na poziomie urządzenia.
W przypadku wykrywania dźwięku za pomocą EventTriggerTypeEnum dostępne są te typy reguł:
| Tryb | Wartość typu wyliczeniowego | Opis |
|---|---|---|
| Dźwięk | Sound |
Ogólne wykrywanie dźwięku. |
| Ktoś coś mówi | PersonTalking |
wykrywa mowę, |
| Szczekanie psa | DogBark |
Wykrywa wokalizacje psów. |
| Odgłos tłuczonego szkła | GlassBreak |
wykrywa odgłos tłuczonego szkła; |
| Alarm z czujnika dymu | SmokeAlarm |
Wykrywa alarmy z czujnika dymu, które często są rozpoznawane po sygnale dźwiękowym T3 (3 krótkie sygnały dźwiękowe, po których następuje przerwa). |
| alarm z czujnika tlenku węgla | CoAlarm |
Wykrywa alarmy z czujników tlenku węgla, które zwykle są rozpoznawane po sygnale dźwiękowym T4 (4 krótkie sygnały dźwiękowe, po których następuje przerwa). |
Sprawdzanie stanu wykrywania dźwięku
Aby wyświetlić użytkownikowi bieżący stan wykrywania dźwięku, musisz sprawdzić, co obsługuje urządzenie i co jest włączone przez sprzęt urządzenia. Sprawdź te 2 atrybuty:
W przypadku programowania na iOS zwykle uzyskujesz dostęp do AvStreamAnalysis cechy z urządzenia, aby odczytać te atrybuty.
// 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) ) ) }
Aktualizowanie zestawu włączonych aktywatorów
Aby zaktualizować zestaw włączonych wyzwalaczy, użyj polecenia
SetOrUpdateEventDetectionTriggers
które przyjmuje listę struktur 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 )
Tryby nagrywania
Cechą RecordingMode jest interfejs do zarządzania nagrywaniem wideo i obrazów na kamerach i dzwonkach do drzwi. Umożliwia użytkownikom wybór między nagrywaniem ciągłym, nagrywaniem zdarzeń lub całkowitym wyłączeniem nagrywania (tylko podgląd na żywo).
Element RecordingModeEnum określa dostępne strategie rejestrowania:
| Tryb | Wartość typu wyliczeniowego | Opis |
|---|---|---|
| Wyłączono | Disabled |
Nagrywanie jest całkowicie wyłączone. Używany głównie przez starsze urządzenia. |
| CVR (Continuous Video Recording) | Cvr |
Filmy są nagrywane przez całą dobę. Wymaga subskrypcji (np. Google Google Home Premium). |
| EBR (nagrywanie zdarzeń) | Ebr |
Nagrywanie jest aktywowane przez zdarzenia (osoba, ruch). Długość wideo zależy od czasu trwania wydarzenia i subskrypcji. |
| ETR (nagrywanie wywoływane zdarzeniem) | Etr |
krótkie nagranie podglądu (np. 10 sekund) wywoływane przez zdarzenia. |
| Widok Live View | LiveView |
Nagrywanie jest wyłączone, ale użytkownicy nadal mogą oglądać transmisję na żywo. |
| Grafika | Images |
Zamiast filmów rejestrowane są migawki, gdy wystąpią zdarzenia. |
Sprawdzanie trybów nagrywania
Aby wyświetlić bieżącą konfigurację nagrywania, sprawdź atrybuty cechy RecordingMode:
supportedRecordingModes– wszystkie potencjalne trybyavailableRecordingModes– wybierane trybyselectedRecordingMode– tryb aktywny
// 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, ) ) } }
Zmiana trybu nagrywania
Przed aktualizacją upewnij się, że wybrany indeks z atrybutu supportedRecordingModes
występuje w atrybucie availableRecordingModes.
Aby zaktualizować wybrany tryb, użyj funkcji
setSelectedRecordingMode, przekazując indeks wybranego trybu:
let recordingModeTrait: Google.RecordingModeTrait let recordingModeID: UInt8 _ = try await recordingModeTrait.update { $0.setSelectedRecordingMode(recordingModeID) }
Inne ustawienia
Za pomocą interfejsów Home API można sterować różnymi innymi ustawieniami.
Włączanie i wyłączanie widzenia w nocy
Aby włączyć lub wyłączyć widzenie w nocy w przypadku kamery, użyj TriStateAutoEnum, aby zaktualizować atrybut nightVision cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji 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
}
}
Zmiana jasności diody LED stanu
Aby zmienić jasność diody LED stanu, użyj
ThreeLevelAutoEnum
do zaktualizowania atrybutu
statusLightBrightness
cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji
setStatusLightBrightness:
// Set the LED brightness
func setStatusLightBrightness(
to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setStatusLightBrightness(value)
}
} catch {
// Error
}
}
Zmiana widocznego obszaru kamery
Widok z kamery jest taki sam jak w przypadku funkcji powiększania i kadrowania opisanej w artykule pomocy Powiększanie i ulepszanie obrazu z kamery Nest.
Obszar wyświetlania jest zdefiniowany w ViewportStruct, który zawiera 4 wartości używane jako współrzędne obszaru wyświetlania. Współrzędne są zdefiniowane w ten sposób:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
Określanie wartości parametru ViewportStruct zależy od interfejsu aplikacji i implementacji kamery. Aby ustawić obszar widoku filmu z kamery na poziomie podstawowym, zaktualizuj atrybut viewport cechy CameraAvStreamManagementTrait za pomocą ViewportStruct, używając wbudowanej funkcji 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
}
}
}
Generowanie struktury TransportOptionsStruct
Niektóre ustawienia wymagają modyfikacji właściwości w TransportOptionsStruct, które są następnie przekazywane do opcji transportu połączenia strumieniowego. W przypadku języka Swift tę strukturę należy wygenerować przed zaktualizowaniem jakichkolwiek właściwości.
Użyj tej funkcji pomocniczej, aby wygenerować strukturę do wykorzystania przy wprowadzaniu tych zmian ustawień:
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
}
Dostosowywanie czułości wybudzania urządzenia
Czułość wybudzania urządzenia służy do oszczędzania baterii poprzez zmniejszenie zakresu, w którym urządzenie może wykrywać aktywność, i wydłużenie czasu wybudzania po wykryciu tej aktywności.
W interfejsach Home API można to ustawić za pomocą właściwości motionSensitivity elementu triggerOptions w transportOptions urządzenia. Te opcje są zdefiniowane w PushAvStreamTransportTrait dla każdego urządzenia.
Czułość wybudzania można ustawić tylko na te wartości:
- 1 = Niski
- 5 = Średni
- 10 = Wysoki
Proces aktualizacji polega na znalezieniu konfiguracji transportu dla aktywnych strumieni nagrywania za pomocą polecenia findTransport, a następnie zmodyfikowaniu konfiguracji za pomocą nowej wartości czułości za pomocą polecenia modifyPushTransport.
Polecenie modifyPushTransport wymaga przekazania pełnego TransportOptionsStruct, więc najpierw musisz skopiować istniejące wartości z bieżącej konfiguracji. Aby to zrobić, zapoznaj się z artykułem Generowanie TransportOptionsStruct dla funkcji pomocniczej.
func setWakeUpSensitivity(to value: UInt8) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionSensitivity != nil else {
// Error - Motion sensitivity not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: value,
maxEventLength: nil
)
)
} catch {
// Error
}
}
Dostosowywanie maksymalnego czasu trwania zdarzenia
Maksymalna długość zdarzenia to czas, przez jaki kamera będzie nagrywać klip w przypadku zdarzenia. Za pomocą interfejsów Home API można skonfigurować dla każdego urządzenia te same długości, co w przypadku Google Home app (GHA), w odstępach sekund:
- 10 sekund
- 15 sekund
- 30 sekund
- 60 sekund (1 minuta)
- 120 sekund (2 minuty)
- 180 sekund (3 minuty)
W interfejsach Home API można to ustawić za pomocą właściwości motionTimeControl elementu triggerOptions w transportOptions urządzenia. Te opcje są zdefiniowane w PushAvStreamTransportTrait dla każdego urządzenia.
Aby zaktualizować konfigurację, znajdź konfigurację transportu dla aktywnych strumieni nagrywania za pomocą polecenia findTransport, a następnie zmodyfikuj konfigurację, podając nową wartość długości zdarzenia, za pomocą polecenia modifyPushTransport.
Polecenie modifyPushTransport wymaga przekazania pełnego TransportOptionsStruct, więc najpierw musisz skopiować istniejące wartości z bieżącej konfiguracji. Aby to zrobić, zapoznaj się z artykułem Generowanie TransportOptionsStruct dla funkcji pomocniczej.
func setMaxEventLength(to value: UInt32) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionTimeControl != nil else {
// Error - Motion time control not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: nil,
maxEventLength: value
)
)
} catch {
// Error
}
}
Włączanie i wyłączanie statystyk
Każde urządzenie może indywidualnie wyrazić zgodę na wysyłanie szczegółowych danych analitycznych do chmury Google Home (patrz Cloud Monitoring for Home APIs).
Aby włączyć analizy na urządzeniu, ustaw wartość właściwości analyticsEnabled)ExtendedGeneralDiagnosticsTrait na true. Gdy ustawisz analyticsEnabled, inna właściwość, logUploadEnabled, zostanie automatycznie ustawiona na true, co umożliwia przesyłanie plików dziennika analitycznego do chmury Google Home.
// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(true)
}
// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(false)
}
Ustawienia dzwonka
Różnymi ustawieniami dzwonka można sterować za pomocą interfejsów Home API.
Zmienianie dźwięku gongu
Aby zmienić dźwięk dzwonka, najpierw pobierz listę dźwięków dzwonka zainstalowanych na urządzeniu, korzystając z atrybutu installedChimeSounds cechy ChimeTrait:
doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
return chimeSound.chimeID, chimeSound.name
}
Następnie zaktualizuj atrybut
selectedChime
cechy ChimeTrait za pomocą wbudowanej funkcji setSelectedChime:
func setDoorbellChime(chimeID: UInt8) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setSelectedChime(chimeID)
}
} catch {
// Error
}
}
Używanie zewnętrznego dzwonka
Dzwonek można skonfigurować tak, aby korzystał z zewnętrznego dzwonka, np. mechanicznego dzwonka zainstalowanego w domu. Należy to skonfigurować podczas instalacji dzwonka, aby uniknąć potencjalnych uszkodzeń zewnętrznego dzwonka.
Aby wskazać typ zainstalowanego dzwonka zewnętrznego, użyj
ExternalChimeType
do zaktualizowania atrybutu
externalChime
cechy ChimeTrait za pomocą wbudowanej funkcji
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
}
}
Zmiana czasu trwania zewnętrznego gongu
Czas dzwonienia zewnętrznego dzwonka w sekundach można skonfigurować za pomocą interfejsów Home API. Jeśli dzwonek zewnętrzny obsługuje czas trwania dzwonka, użytkownik może chcieć go skonfigurować.
Wartość ustawiona w tym miejscu zależy od specyfikacji zewnętrznego gongu i zalecanej długości dzwonka.
Aby zmienić czas trwania dzwonka zewnętrznego, zaktualizuj atrybut externalChimeDurationSeconds cechy ChimeTrait za pomocą wbudowanej funkcji setExternalChimeDurationSeconds:
// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setExternalChimeDuration(value)
}
} catch {
// Error
}
}
Włączanie motywu dzwonka
Niektóre dzwonki mogą mieć dzwonki, które są dostępne dla użytkowników tylko przez ograniczony czas. Na przykład dzwonki związane ze świętami. Są one nazywane motywami dzwonka.
Aby sprawdzić, które motywy dzwonka są dostępne dla użytkownika, utwórz filtr przedziału czasowego i użyj go do filtrowania wyników polecenia
getAvailableThemes
z cechy
ChimeThemes. Zwróci to listę dostępnych motywów, w tym ich nazwy.
Poniższy przykład pokazuje, jak filtrować listę.
Motyw jest uznawany za aktywny, jeśli bieżący czas mieści się w zakresie czasu rozpoczęcia i czasu zakończenia (odpowiednio wartości startTimeSeconds i endTimeSeconds). Jeśli czas rozpoczęcia nie jest ustawiony, jest on uznawany za aktywny od początku. Jeśli nie ustawisz czasu zakończenia, będzie ona aktywna bezterminowo. Jeśli brakuje obu tych elementów, motyw jest zawsze aktywny.
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)
}
}
}
Gdy poznasz nazwę motywu, np. Christmas, możesz go wybrać za pomocą funkcji setSelectedTimeboxedThemeName()
w atrybucie ChimeThemes ChimeThemes.
private func setChimeTheme(to value: String) async throws {
_ = try await chimeThemeTrait.update {
$0.setSelectedTimeboxedThemeName(value)
}
}```