From 4de244bb9b4516759183c3f4af778d00a59c9056 Mon Sep 17 00:00:00 2001 From: dgreif Date: Fri, 7 Jun 2019 13:15:16 -0700 Subject: [PATCH] fix: use api to turn light groups on/off --- api/location.ts | 17 +++++++++++++++++ api/rest-client.ts | 11 +++++++---- api/ring-types.ts | 1 + homebridge/README.md | 1 + homebridge/beam.ts | 9 +++++++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/api/location.ts b/api/location.ts index 9e926e82..cbe4eb3b 100644 --- a/api/location.ts +++ b/api/location.ts @@ -339,6 +339,23 @@ export class Location { return this.sendCommandToSecurityPanel('security-panel.silence-siren') } + setLightGroup(groupId: string, on: boolean, durationSeconds = 60) { + console.log('SETTING LIGHT GROUP', groupId, on, durationSeconds) + this.restClient.request( + 'POST', + `https://api.ring.com/groups/v1/locations/${ + this.locationId + }/groups/${groupId}/devices`, + { + lights_on: { + duration_seconds: durationSeconds, + enabled: on + } + }, + true + ) + } + getNextMessageOfType(type: MessageType, src: string) { return this.onMessage .pipe( diff --git a/api/rest-client.ts b/api/rest-client.ts index 916bfeb7..e61c2244 100644 --- a/api/rest-client.ts +++ b/api/rest-client.ts @@ -62,11 +62,14 @@ export class RingRestClient { async request( method: 'GET' | 'POST', url: string, - data?: any + data?: any, + json = false ): Promise { const token = await this.authTokenPromise const headers = { - 'content-type': 'application/x-www-form-urlencoded', + 'content-type': json + ? 'application/json' + : 'application/x-www-form-urlencoded', authorization: `Bearer ${token}` } @@ -74,7 +77,7 @@ export class RingRestClient { return await requestWithRetry({ method, url, - data: querystring.stringify(data), + data: json ? data : querystring.stringify(data), headers }) } catch (e) { @@ -82,7 +85,7 @@ export class RingRestClient { if (response.status === 401) { this.authTokenPromise = this.getAuthToken() - return this.request(method, url, data) + return this.request(method, url, data, json) } if ( diff --git a/api/ring-types.ts b/api/ring-types.ts index 307d3562..f6f433ce 100644 --- a/api/ring-types.ts +++ b/api/ring-types.ts @@ -88,6 +88,7 @@ export interface RingDeviceData { co?: { alarmStatus?: 'active' } smoke?: { alarmStatus?: 'active' } motionStatus?: 'clear' | 'faulted' + groupId?: string // switch on?: boolean diff --git a/homebridge/README.md b/homebridge/README.md index d1ccd8f3..665728a0 100644 --- a/homebridge/README.md +++ b/homebridge/README.md @@ -44,6 +44,7 @@ This works well if you automatically arm/disarm on leave/arrive (see setup instr when you turn on a light via the Ring app. To force a duration when the light is turned on from HomeKit, set this option to a specific number of seconds. If this option is not set, the lights will use the duration from the previous time the light was turned on in the Ring app. +For light groups, this will default to 60 seconds. The maximum value is `32767`, which is ~9.1 hours. `hideLightGroups`: Ring smart lighting allows you to create lighting groups within the Ring app. diff --git a/homebridge/beam.ts b/homebridge/beam.ts index 662c8dea..1724a3b7 100644 --- a/homebridge/beam.ts +++ b/homebridge/beam.ts @@ -4,6 +4,10 @@ import { RingAlarmPlatformConfig } from './config' import { BaseAccessory } from './base-accessory' export class Beam extends BaseAccessory { + isLightGroup = + this.device.data.deviceType === RingDeviceType.BeamsLightGroupSwitch + groupId = this.device.data.groupId + constructor( public readonly device: RingDevice, public readonly accessory: HAP.Accessory, @@ -53,6 +57,11 @@ export class Beam extends BaseAccessory { const duration = beamDurationSeconds ? Math.min(beamDurationSeconds, 32767) : undefined + + if (this.isLightGroup && this.groupId) { + return this.device.location.setLightGroup(this.groupId, on, duration) + } + const data = on ? { lightMode: 'on', duration } : { lightMode: 'default' } return this.device.sendCommand('light-mode.set', data)