diff --git a/packages/examples/api-example.ts b/packages/examples/api-example.ts index 6b8443c8..d0911a50 100644 --- a/packages/examples/api-example.ts +++ b/packages/examples/api-example.ts @@ -46,16 +46,16 @@ async function example() { }) console.log('Got events', eventsResponse.events[0]) const eventsWithRecordings = eventsResponse.events.filter( - (event) => event.recording_status === 'ready' + (event) => event.recording_status === 'ready', ), transcodedUrl = await camera.getRecordingUrl( eventsWithRecordings[0].ding_id_str, // MUST use the ding_id_str, not ding_id { transcoded: true, // get transcoded version of the video. false by default. transcoded has ring log and timestamp - } + }, ), untranscodedUrl = await camera.getRecordingUrl( - eventsWithRecordings[0].ding_id_str + eventsWithRecordings[0].ding_id_str, ) console.log('Recording Transcoded URL', transcodedUrl) diff --git a/packages/examples/browser-example.ts b/packages/examples/browser-example.ts index 120a1a80..7bca98d1 100644 --- a/packages/examples/browser-example.ts +++ b/packages/examples/browser-example.ts @@ -29,7 +29,7 @@ async function example() { app.use('/', express.static(path.join(__dirname, 'public'))) app.listen(3000, () => { console.log( - 'Listening on port 3000. Go to http://localhost:3000 in your browser' + 'Listening on port 3000. Go to http://localhost:3000 in your browser', ) }) @@ -62,10 +62,13 @@ async function example() { process.exit() }) - setTimeout(function () { - console.log('Stopping call...') - call.stop() - }, 5 * 60 * 1000) // Stop after 5 minutes. + setTimeout( + function () { + console.log('Stopping call...') + call.stop() + }, + 5 * 60 * 1000, + ) // Stop after 5 minutes. } example().catch((e) => { diff --git a/packages/examples/example.ts b/packages/examples/example.ts index a675ba0c..d71b37eb 100644 --- a/packages/examples/example.ts +++ b/packages/examples/example.ts @@ -15,7 +15,7 @@ async function example() { allCameras = await ringApi.getCameras() console.log( - `Found ${locations.length} location(s) with ${allCameras.length} camera(s).` + `Found ${locations.length} location(s) with ${allCameras.length} camera(s).`, ) ringApi.onRefreshTokenUpdated.subscribe( @@ -32,7 +32,7 @@ async function example() { .replace(oldRefreshToken, newRefreshToken) await promisify(writeFile)('.env', updatedConfig) - } + }, ) for (const location of locations) { @@ -47,7 +47,7 @@ async function example() { devices = await location.getDevices() console.log( - `\nLocation ${location.name} (${location.id}) has the following ${cameras.length} camera(s):` + `\nLocation ${location.name} (${location.id}) has the following ${cameras.length} camera(s):`, ) for (const camera of cameras) { @@ -55,7 +55,7 @@ async function example() { } console.log( - `\nLocation ${location.name} (${location.id}) has the following ${devices.length} device(s):` + `\nLocation ${location.name} (${location.id}) has the following ${devices.length} device(s):`, ) for (const device of devices) { @@ -76,7 +76,7 @@ async function example() { console.log( `${event} on ${camera.name} camera. Ding id ${ notification.ding.id - }. Received at ${new Date()}` + }. Received at ${new Date()}`, ) }) }) diff --git a/packages/homebridge-ring/base-accessory.ts b/packages/homebridge-ring/base-accessory.ts index b129f983..67d8dffe 100644 --- a/packages/homebridge-ring/base-accessory.ts +++ b/packages/homebridge-ring/base-accessory.ts @@ -15,7 +15,7 @@ import { import { logError, logInfo } from 'ring-client-api/util' function isServiceInstance( - serviceType: WithUUID | Service + serviceType: WithUUID | Service, ): serviceType is Service { return typeof (serviceType as any) === 'object' } @@ -36,7 +36,7 @@ export abstract class BaseAccessory { getService( serviceType: ServiceType, name = this.device.name, - subType?: string + subType?: string, ) { if (isServiceInstance(serviceType)) { return serviceType @@ -60,7 +60,7 @@ export abstract class BaseAccessory { name !== existingService.displayName ) { throw new Error( - `Overlapping services for device ${this.device.name} - ${name} != ${existingService.displayName} - ${serviceType}` + `Overlapping services for device ${this.device.name} - ${name} != ${existingService.displayName} - ${serviceType}`, ) } @@ -110,7 +110,7 @@ export abstract class BaseAccessory { } catch (e: any) { callback(e) } - } + }, ) }) } @@ -120,13 +120,13 @@ export abstract class BaseAccessory { CharacteristicEventTypes.SET, ( newValue: CharacteristicValue, - callback: CharacteristicSetCallback + callback: CharacteristicSetCallback, ) => { Promise.resolve(setValue(newValue as U)).catch((e) => { logError(e) }) callback() - } + }, ) } } @@ -147,7 +147,7 @@ export abstract class BaseAccessory { service.UUID, service.displayName || service.name, 'from', - this.device.name + this.device.name, ) this.accessory.removeService(service) diff --git a/packages/homebridge-ring/base-data-accessory.ts b/packages/homebridge-ring/base-data-accessory.ts index d9215d94..7b2c9e15 100644 --- a/packages/homebridge-ring/base-data-accessory.ts +++ b/packages/homebridge-ring/base-data-accessory.ts @@ -22,7 +22,7 @@ import { import { logError } from 'ring-client-api/util' export abstract class BaseDataAccessory< - T extends RingDevice | RingCamera | RingChime | RingIntercom + T extends RingDevice | RingCamera | RingChime | RingIntercom, > extends BaseAccessory { abstract readonly device: T abstract readonly accessory: PlatformAccessory @@ -63,7 +63,7 @@ export abstract class BaseDataAccessory< } catch (e: any) { callback(e) } - } + }, ) } @@ -74,11 +74,11 @@ export abstract class BaseDataAccessory< CharacteristicEventTypes.SET, ( newValue: CharacteristicValue, - callback: CharacteristicSetCallback + callback: CharacteristicSetCallback, ) => { onValueToSet.next(newValue) callback() - } + }, ) onValueToSet.pipe(debounceTime(setValueDebounceTime)).subscribe(setValue) @@ -87,11 +87,11 @@ export abstract class BaseDataAccessory< CharacteristicEventTypes.SET, ( newValue: CharacteristicValue, - callback: CharacteristicSetCallback + callback: CharacteristicSetCallback, ) => { Promise.resolve(setValue(newValue)).catch(logError) callback() - } + }, ) } diff --git a/packages/homebridge-ring/beam.ts b/packages/homebridge-ring/beam.ts index ced46630..39a4b4bb 100644 --- a/packages/homebridge-ring/beam.ts +++ b/packages/homebridge-ring/beam.ts @@ -13,7 +13,7 @@ export class Beam extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/brightness-only.ts b/packages/homebridge-ring/brightness-only.ts index 56849813..d2b84c13 100644 --- a/packages/homebridge-ring/brightness-only.ts +++ b/packages/homebridge-ring/brightness-only.ts @@ -9,7 +9,7 @@ export class BrightnessOnly extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/camera-source.ts b/packages/homebridge-ring/camera-source.ts index b6febf8b..b9e09c8d 100644 --- a/packages/homebridge-ring/camera-source.ts +++ b/packages/homebridge-ring/camera-source.ts @@ -69,19 +69,19 @@ class StreamingSessionWrapper { libfdkAacInstalledPromise = doesFfmpegSupportCodec( 'libfdk_aac', - getFfmpegPath() + getFfmpegPath(), ) .then((supported) => { if (!supported) { logError( - 'Streaming video only - found ffmpeg, but libfdk_aac is not installed. See https://github.com/dgreif/ring/wiki/FFmpeg for details.' + 'Streaming video only - found ffmpeg, but libfdk_aac is not installed. See https://github.com/dgreif/ring/wiki/FFmpeg for details.', ) } return supported }) .catch(() => { logError( - 'Streaming video only - ffmpeg was not found. See https://github.com/dgreif/ring/wiki/FFmpeg for details.' + 'Streaming video only - ffmpeg was not found. See https://github.com/dgreif/ring/wiki/FFmpeg for details.', ) return false }) @@ -90,7 +90,7 @@ class StreamingSessionWrapper { public streamingSession: StreamingSession, public prepareStreamRequest: PrepareStreamRequest, public ringCamera: RingCamera, - public start: number + public start: number, ) { const { targetAddress, @@ -119,10 +119,10 @@ class StreamingSessionWrapper { logInfo( `Live stream for ${ this.ringCamera.name - } appears to be inactive. (${getDurationSeconds(start)}s)` + } appears to be inactive. (${getDurationSeconds(start)}s)`, ) streamingSession.stop() - }) + }), ) // Periodically send a blank RTCP packet to the HomeKit video port @@ -147,7 +147,7 @@ class StreamingSessionWrapper { address: targetAddress, }) .catch(logError) - }) + }), ) } @@ -241,7 +241,7 @@ class StreamingSessionWrapper { logInfo( `Received stream data from ${ this.ringCamera.name - } (${getDurationSeconds(this.start)}s)` + } (${getDurationSeconds(this.start)}s)`, ) } @@ -251,7 +251,7 @@ class StreamingSessionWrapper { address: targetAddress, }) .catch(logError) - }) + }), ) const shouldTranscodeAudio = await this.libfdkAacInstalledPromise @@ -314,7 +314,7 @@ class StreamingSessionWrapper { srtpSalt: remoteAudioSrtpSalt, }, audioSrtpSession = new SrtpSession( - getSessionConfig(remoteAudioSrtpOptions) + getSessionConfig(remoteAudioSrtpOptions), ), returnAudioTranscodedSplitter = new RtpSplitter(({ message }) => { if (!cameraSpeakerActive) { @@ -433,7 +433,10 @@ export class CameraSource implements CameraStreamingDelegate { private sessions: { [sessionKey: string]: StreamingSessionWrapper } = {} private cachedSnapshot?: Buffer - constructor(private ringCamera: RingCamera, private useOpus = false) {} + constructor( + private ringCamera: RingCamera, + private useOpus = false, + ) {} private previousLoadSnapshotPromise?: Promise async loadSnapshot(imageUuid?: string) { @@ -461,7 +464,7 @@ export class CameraSource implements CameraStreamingDelegate { logDebug( `Loading new snapshot into cache for ${this.ringCamera.name}${ imageUuid ? ' by uuid' : '' - }` + }`, ) try { @@ -472,17 +475,20 @@ export class CameraSource implements CameraStreamingDelegate { if (previousSnapshot !== newSnapshot) { // Keep the snapshots in cache 2 minutes longer than their lifetime // This allows users on LTE with wired camera to get snapshots each 60 second pull even though the cached snapshot is out of date - setTimeout(() => { - if (this.cachedSnapshot === newSnapshot) { - this.cachedSnapshot = undefined - } - }, this.ringCamera.snapshotLifeTime + 2 * 60 * 1000) + setTimeout( + () => { + if (this.cachedSnapshot === newSnapshot) { + this.cachedSnapshot = undefined + } + }, + this.ringCamera.snapshotLifeTime + 2 * 60 * 1000, + ) } logDebug( `Snapshot cached for ${this.ringCamera.name}${ imageUuid ? ' by uuid' : '' - } (${getDurationSeconds(start)}s)` + } (${getDurationSeconds(start)}s)`, ) } catch (e: any) { this.cachedSnapshot = undefined @@ -490,10 +496,10 @@ export class CameraSource implements CameraStreamingDelegate { `Failed to cache snapshot for ${ this.ringCamera.name } (${getDurationSeconds( - start + start, )}s), The camera currently reports that it is ${ this.ringCamera.isOffline ? 'offline' : 'online' - }` + }`, ) // log additioanl snapshot error message if one is present @@ -515,7 +521,7 @@ export class CameraSource implements CameraStreamingDelegate { logDebug( `${ this.cachedSnapshot ? 'Used cached snapshot' : 'No snapshot cached' - } for ${this.ringCamera.name}` + } for ${this.ringCamera.name}`, ) if (!this.ringCamera.hasSnapshotWithinLifetime) { @@ -528,7 +534,7 @@ export class CameraSource implements CameraStreamingDelegate { async handleSnapshotRequest( request: SnapshotRequest, - callback: SnapshotRequestCallback + callback: SnapshotRequestCallback, ) { try { const snapshot = await this.getCurrentSnapshot() @@ -550,7 +556,7 @@ export class CameraSource implements CameraStreamingDelegate { async prepareStream( request: PrepareStreamRequest, - callback: PrepareStreamCallback + callback: PrepareStreamCallback, ) { const start = Date.now() logInfo(`Preparing Live Stream for ${this.ringCamera.name}`) @@ -561,15 +567,15 @@ export class CameraSource implements CameraStreamingDelegate { liveCall, request, this.ringCamera, - start + start, ) this.sessions[request.sessionID] = session logInfo( `Stream Prepared for ${this.ringCamera.name} (${getDurationSeconds( - start - )}s)` + start, + )}s)`, ) callback(undefined, { @@ -590,7 +596,7 @@ export class CameraSource implements CameraStreamingDelegate { logError( `Failed to prepare stream for ${ this.ringCamera.name - } (${getDurationSeconds(start)}s)` + } (${getDurationSeconds(start)}s)`, ) logError(e) callback(e) @@ -599,7 +605,7 @@ export class CameraSource implements CameraStreamingDelegate { async handleStreamRequest( request: StreamingRequest, - callback: StreamRequestCallback + callback: StreamRequestCallback, ) { const sessionID = request.sessionID, session = this.sessions[sessionID], @@ -613,8 +619,8 @@ export class CameraSource implements CameraStreamingDelegate { if (requestType === 'start') { logInfo( `Activating stream for ${this.ringCamera.name} (${getDurationSeconds( - session.start - )}s)` + session.start, + )}s)`, ) try { await session.activate(request) @@ -627,8 +633,8 @@ export class CameraSource implements CameraStreamingDelegate { } logInfo( `Streaming active for ${this.ringCamera.name} (${getDurationSeconds( - session.start - )}s)` + session.start, + )}s)`, ) } else if (requestType === 'stop') { logInfo(`Stopped Live Stream for ${this.ringCamera.name}`) diff --git a/packages/homebridge-ring/camera.ts b/packages/homebridge-ring/camera.ts index 42f61820..141c8274 100644 --- a/packages/homebridge-ring/camera.ts +++ b/packages/homebridge-ring/camera.ts @@ -13,13 +13,13 @@ export class Camera extends BaseDataAccessory { private inHomeDoorbellStatus: boolean | undefined private cameraSource = new CameraSource( this.device, - this.config.unbridgeCameras + this.config.unbridgeCameras, ) constructor( public readonly device: RingCamera, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -58,7 +58,7 @@ export class Camera extends BaseDataAccessory { } return this.loadSnapshotForEvent('Detected Motion', true) - }) + }), ), }) } @@ -72,9 +72,9 @@ export class Camera extends BaseDataAccessory { switchMap(() => { return this.loadSnapshotForEvent( 'Doorbell Pressed', - Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS + Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS, ) - }) + }), ), }) @@ -83,7 +83,7 @@ export class Camera extends BaseDataAccessory { characteristicType: Characteristic.ProgrammableSwitchEvent, serviceType: Service.StatelessProgrammableSwitch, onValue: device.onDoorbellPressed.pipe( - mapTo(Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS) + mapTo(Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS), ), }) @@ -125,7 +125,7 @@ export class Camera extends BaseDataAccessory { name: device.name + ' Siren', getValue: (data) => { return Boolean( - data.siren_status && data.siren_status.seconds_remaining + data.siren_status && data.siren_status.seconds_remaining, ) }, setValue: (value) => device.setSiren(value), @@ -137,7 +137,7 @@ export class Camera extends BaseDataAccessory { this.device.onInHomeDoorbellStatus.subscribe( (data: boolean | undefined) => { this.inHomeDoorbellStatus = data - } + }, ) this.registerObservableCharacteristic({ characteristicType: Characteristic.On, @@ -203,7 +203,7 @@ export class Camera extends BaseDataAccessory { onValue: device.onBatteryLevel.pipe( map((batteryLevel) => { return batteryLevel === null ? 100 : batteryLevel - }) + }), ), }) } @@ -211,7 +211,7 @@ export class Camera extends BaseDataAccessory { private async loadSnapshotForEvent( eventDescription: string, - characteristicValue: T + characteristicValue: T, ) { let imageUuid = this.device.latestNotificationSnapshotUuid @@ -224,8 +224,8 @@ export class Camera extends BaseDataAccessory { await Promise.race([ firstValueFrom( this.device.onNewNotification.pipe( - filter((notification) => Boolean(notification.ding.image_uuid)) - ) + filter((notification) => Boolean(notification.ding.image_uuid)), + ), ), // wait up to 2 seconds for the second notification delay(2000), @@ -241,7 +241,7 @@ export class Camera extends BaseDataAccessory { logInfo( this.device.name + - ` ${eventDescription}. Loading snapshot before sending event to HomeKit` + ` ${eventDescription}. Loading snapshot before sending event to HomeKit`, ) try { @@ -249,7 +249,7 @@ export class Camera extends BaseDataAccessory { } catch (e) { logInfo( this.device.name + - ' Failed to load snapshot. Sending event to HomeKit without new snapshot' + ' Failed to load snapshot. Sending event to HomeKit without new snapshot', ) } diff --git a/packages/homebridge-ring/chime.ts b/packages/homebridge-ring/chime.ts index 89c08bd3..9eec5724 100644 --- a/packages/homebridge-ring/chime.ts +++ b/packages/homebridge-ring/chime.ts @@ -11,24 +11,24 @@ export class Chime extends BaseDataAccessory { constructor( public readonly device: RingChime, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() const { Characteristic, Service } = hap, snoozeService = this.getService( Service.Switch, device.name + ' Snooze', - 'snooze' + 'snooze', ), playDingService = this.getService( Service.Switch, device.name + ' Play Ding', - 'play-ding' + 'play-ding', ), playMotionService = this.getService( Service.Switch, device.name + ' Play Motion', - 'play-motion' + 'play-motion', ) // Snooze Switch diff --git a/packages/homebridge-ring/co-alarm.ts b/packages/homebridge-ring/co-alarm.ts index 70d4e048..645d0124 100644 --- a/packages/homebridge-ring/co-alarm.ts +++ b/packages/homebridge-ring/co-alarm.ts @@ -8,7 +8,7 @@ export class CoAlarm extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/config.ts b/packages/homebridge-ring/config.ts index b23f642b..2b8c43e7 100644 --- a/packages/homebridge-ring/config.ts +++ b/packages/homebridge-ring/config.ts @@ -28,7 +28,7 @@ export interface RingPlatformConfig extends RingApiOptions { export function updateHomebridgeConfig( homebridge: API, - update: (config: string) => string + update: (config: string) => string, ) { const configPath = homebridge.user.configPath(), config = readFileSync(configPath).toString(), @@ -55,7 +55,7 @@ export function getSystemId(homebridgeStoragePath: string) { try { const ringContext: RingContext = JSON.parse( - readFileSync(filePath).toString() + readFileSync(filePath).toString(), ) if (ringContext.systemId) { return ringContext.systemId diff --git a/packages/homebridge-ring/contact-sensor.ts b/packages/homebridge-ring/contact-sensor.ts index 56162fbe..ca830cc6 100644 --- a/packages/homebridge-ring/contact-sensor.ts +++ b/packages/homebridge-ring/contact-sensor.ts @@ -8,7 +8,7 @@ export class ContactSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/fan.ts b/packages/homebridge-ring/fan.ts index ea8d14bb..a731ffc5 100644 --- a/packages/homebridge-ring/fan.ts +++ b/packages/homebridge-ring/fan.ts @@ -9,7 +9,7 @@ export class Fan extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/flood-freeze-sensor.ts b/packages/homebridge-ring/flood-freeze-sensor.ts index 25b98cba..8d2774bb 100644 --- a/packages/homebridge-ring/flood-freeze-sensor.ts +++ b/packages/homebridge-ring/flood-freeze-sensor.ts @@ -10,7 +10,7 @@ export class FloodFreezeSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -21,7 +21,7 @@ export class FloodFreezeSensor extends BaseDeviceAccessory { leakService = this.getService(LeakSensor, `${device.name} Flood Sensor`), freezeService = this.getService( OccupancySensor, - `${device.name} Freeze Sensor` + `${device.name} Freeze Sensor`, ), onFloodDetected = device.onData.pipe( map((data) => { @@ -29,7 +29,7 @@ export class FloodFreezeSensor extends BaseDeviceAccessory { ? LeakDetected.LEAK_DETECTED : LeakDetected.LEAK_NOT_DETECTED }), - distinctUntilChanged() + distinctUntilChanged(), ), onFreezeDetected = device.onData.pipe( map((data) => { @@ -37,7 +37,7 @@ export class FloodFreezeSensor extends BaseDeviceAccessory { ? OccupancyDetected.OCCUPANCY_DETECTED : OccupancyDetected.OCCUPANCY_NOT_DETECTED }), - distinctUntilChanged() + distinctUntilChanged(), ) this.initSensorService(leakService) diff --git a/packages/homebridge-ring/freeze-sensor.ts b/packages/homebridge-ring/freeze-sensor.ts index 7247f53e..d7a77b4e 100644 --- a/packages/homebridge-ring/freeze-sensor.ts +++ b/packages/homebridge-ring/freeze-sensor.ts @@ -10,7 +10,7 @@ export class FreezeSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -24,7 +24,7 @@ export class FreezeSensor extends BaseDeviceAccessory { ? OccupancyDetected.OCCUPANCY_DETECTED : OccupancyDetected.OCCUPANCY_NOT_DETECTED }), - distinctUntilChanged() + distinctUntilChanged(), ) this.initSensorService(OccupancySensor) diff --git a/packages/homebridge-ring/intercom.ts b/packages/homebridge-ring/intercom.ts index ce44c92a..5dc52bae 100644 --- a/packages/homebridge-ring/intercom.ts +++ b/packages/homebridge-ring/intercom.ts @@ -13,7 +13,7 @@ export class Intercom extends BaseDataAccessory { constructor( public readonly device: RingIntercom, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() const { Characteristic, Service } = hap, @@ -21,11 +21,11 @@ export class Intercom extends BaseDataAccessory { { LockCurrentState, LockTargetState, ProgrammableSwitchEvent } = Characteristic, programableSwitchService = this.getService( - Service.StatelessProgrammableSwitch + Service.StatelessProgrammableSwitch, ), onDoorbellPressed = device.onDing.pipe( throttleTime(15000), - map(() => ProgrammableSwitchEvent.SINGLE_PRESS) + map(() => ProgrammableSwitchEvent.SINGLE_PRESS), ), syncLockState = () => { const state = this.getLockState() @@ -120,7 +120,7 @@ export class Intercom extends BaseDataAccessory { onValue: device.onBatteryLevel.pipe( map((batteryLevel) => { return batteryLevel === null ? 100 : batteryLevel - }) + }), ), requestUpdate: () => device.requestUpdate(), }) diff --git a/packages/homebridge-ring/location-mode-switch.ts b/packages/homebridge-ring/location-mode-switch.ts index 661a5177..498e3e08 100644 --- a/packages/homebridge-ring/location-mode-switch.ts +++ b/packages/homebridge-ring/location-mode-switch.ts @@ -37,7 +37,7 @@ export class LocationModeSwitch extends BaseAccessory { constructor( private readonly location: Location, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() const { @@ -47,10 +47,10 @@ export class LocationModeSwitch extends BaseAccessory { accessoryName = location.name + ' Mode', service = this.getService(SecuritySystem, accessoryName), currentState = service.getCharacteristic( - Characteristic.SecuritySystemCurrentState + Characteristic.SecuritySystemCurrentState, ), targetState = service.getCharacteristic( - Characteristic.SecuritySystemTargetState + Characteristic.SecuritySystemTargetState, ), getCurrentMode = () => { return firstValueFrom(location.onLocationMode) @@ -85,7 +85,7 @@ export class LocationModeSwitch extends BaseAccessory { } callback(null, state) - } + }, ) targetState.on( @@ -95,16 +95,16 @@ export class LocationModeSwitch extends BaseAccessory { null, this.targetState !== undefined ? this.targetState - : await getCurrentState() + : await getCurrentState(), ) - } + }, ) targetState.on( CharacteristicEventTypes.SET, async ( state: CharacteristicValue, - callback: CharacteristicSetCallback + callback: CharacteristicSetCallback, ) => { const { Characteristic: { SecuritySystemTargetState: State }, @@ -134,7 +134,7 @@ export class LocationModeSwitch extends BaseAccessory { } logInfo(`Setting ${this.location.name} Mode to home`) return this.location.setLocationMode('home') - } + }, ) targetState.setProps({ diff --git a/packages/homebridge-ring/lock.ts b/packages/homebridge-ring/lock.ts index 0c7c8ea9..877811d7 100644 --- a/packages/homebridge-ring/lock.ts +++ b/packages/homebridge-ring/lock.ts @@ -28,7 +28,7 @@ export class Lock extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/motion-sensor.ts b/packages/homebridge-ring/motion-sensor.ts index e80dd296..1290a55a 100644 --- a/packages/homebridge-ring/motion-sensor.ts +++ b/packages/homebridge-ring/motion-sensor.ts @@ -8,7 +8,7 @@ export class MotionSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/multi-level-switch.ts b/packages/homebridge-ring/multi-level-switch.ts index 0918481f..eee316dc 100644 --- a/packages/homebridge-ring/multi-level-switch.ts +++ b/packages/homebridge-ring/multi-level-switch.ts @@ -9,7 +9,7 @@ export class MultiLevelSwitch extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/outlet.ts b/packages/homebridge-ring/outlet.ts index a1bf0c14..9f6b2c84 100644 --- a/packages/homebridge-ring/outlet.ts +++ b/packages/homebridge-ring/outlet.ts @@ -9,7 +9,7 @@ export class Outlet extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/panic-buttons.ts b/packages/homebridge-ring/panic-buttons.ts index 5f3a5215..d7cc6d8c 100644 --- a/packages/homebridge-ring/panic-buttons.ts +++ b/packages/homebridge-ring/panic-buttons.ts @@ -18,7 +18,7 @@ const burglarStates: AlarmState[] = [ function matchesAnyAlarmState( { alarmInfo }: RingDeviceData, - targetStates: AlarmState[] + targetStates: AlarmState[], ) { return Boolean(alarmInfo && targetStates.includes(alarmInfo.state)) } @@ -27,7 +27,7 @@ export class PanicButtons extends BaseDataAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/ring-platform.ts b/packages/homebridge-ring/ring-platform.ts index 268562e0..404a933e 100644 --- a/packages/homebridge-ring/ring-platform.ts +++ b/packages/homebridge-ring/ring-platform.ts @@ -66,7 +66,7 @@ export const platformName = 'Ring' export const pluginName = 'homebridge-ring' function getAccessoryClass( - device: RingDevice + device: RingDevice, ): (new (...args: any[]) => BaseAccessory) | null { const { deviceType } = device @@ -149,7 +149,7 @@ export class RingPlatform implements DynamicPlatformPlugin { constructor( public log: Logging, public config: PlatformConfig & RingPlatformConfig & RefreshTokenAuth, - public api: API + public api: API, ) { if (!config.disableLogs) { useLogger({ @@ -179,7 +179,7 @@ export class RingPlatform implements DynamicPlatformPlugin { }) } else { this.log.warn( - 'Plugin is not configured. Visit https://github.com/dgreif/ring/tree/main/packages/homebridge-ring#homebridge-configuration for more information.' + 'Plugin is not configured. Visit https://github.com/dgreif/ring/tree/main/packages/homebridge-ring#homebridge-configuration for more information.', ) } }) @@ -189,7 +189,7 @@ export class RingPlatform implements DynamicPlatformPlugin { configureAccessory(accessory: PlatformAccessory) { logInfo( - `Configuring cached accessory ${accessory.UUID} ${accessory.displayName}` + `Configuring cached accessory ${accessory.UUID} ${accessory.displayName}`, ) this.log.debug('%j', accessory) this.homebridgeAccessories[accessory.UUID] = accessory @@ -221,7 +221,7 @@ export class RingPlatform implements DynamicPlatformPlugin { { cameras, chimes, intercoms } = location, allDevices = [...devices, ...cameras, ...chimes, ...intercoms], securityPanel = devices.find( - (x) => x.deviceType === RingDeviceType.SecurityPanel + (x) => x.deviceType === RingDeviceType.SecurityPanel, ), debugPrefix = debug ? 'TEST ' : '', hapDevices = allDevices.map((device) => { @@ -277,7 +277,7 @@ export class RingPlatform implements DynamicPlatformPlugin { } logInfo( - `Configuring ${cameras.length} cameras and ${hapDevices.length} devices for location "${location.name}" - locationId: ${location.id}` + `Configuring ${cameras.length} cameras and ${hapDevices.length} devices for location "${location.name}" - locationId: ${location.id}`, ) hapDevices.forEach( ({ deviceType, device, isCamera, id, name, AccessoryClass }) => { @@ -301,7 +301,7 @@ export class RingPlatform implements DynamicPlatformPlugin { if (isExternalCamera && this.homebridgeAccessories[uuid]) { // Camera was previously bridged. Remove it from the platform so that it can be added as an external accessory this.log.warn( - `Camera ${displayName} was previously bridged. You will need to manually pair it as a new accessory.` + `Camera ${displayName} was previously bridged. You will need to manually pair it as a new accessory.`, ) this.api.unregisterPlatformAccessories(pluginName, platformName, [ this.homebridgeAccessories[uuid], @@ -315,17 +315,17 @@ export class RingPlatform implements DynamicPlatformPlugin { uuid, isCamera ? hap.Categories.CAMERA - : hap.Categories.SECURITY_SYSTEM + : hap.Categories.SECURITY_SYSTEM, ) if (isExternalCamera) { logInfo( - `Configured camera ${uuid} ${deviceType} ${displayName}` + `Configured camera ${uuid} ${deviceType} ${displayName}`, ) externalAccessories.push(accessory) } else { logInfo( - `Adding new accessory ${uuid} ${deviceType} ${displayName}` + `Adding new accessory ${uuid} ${deviceType} ${displayName}`, ) platformAccessories.push(accessory) } @@ -337,7 +337,7 @@ export class RingPlatform implements DynamicPlatformPlugin { ) { // This is a one-time cleanup that will remove persist files for old external accessories from unbridged cameras hap.Accessory.cleanupAccessoryData( - generateMacAddress(accessory.UUID) + generateMacAddress(accessory.UUID), ) } @@ -348,22 +348,22 @@ export class RingPlatform implements DynamicPlatformPlugin { accessory = new AccessoryClass( device as any, homebridgeAccessory, - config + config, ) accessory.initBase() this.homebridgeAccessories[uuid] = homebridgeAccessory activeAccessoryIds.push(uuid) - } + }, ) - }) + }), ) if (platformAccessories.length) { api.registerPlatformAccessories( pluginName, platformName, - platformAccessories + platformAccessories, ) } @@ -377,7 +377,7 @@ export class RingPlatform implements DynamicPlatformPlugin { staleAccessories.forEach((staleAccessory) => { logInfo( - `Removing stale cached accessory ${staleAccessory.UUID} ${staleAccessory.displayName}` + `Removing stale cached accessory ${staleAccessory.UUID} ${staleAccessory.displayName}`, ) }) @@ -385,7 +385,7 @@ export class RingPlatform implements DynamicPlatformPlugin { this.api.unregisterPlatformAccessories( pluginName, platformName, - staleAccessories + staleAccessories, ) } @@ -398,7 +398,7 @@ export class RingPlatform implements DynamicPlatformPlugin { updateHomebridgeConfig(this.api, (configContents) => { return configContents.replace(oldRefreshToken, newRefreshToken) }) - } + }, ) } } diff --git a/packages/homebridge-ring/security-panel.ts b/packages/homebridge-ring/security-panel.ts index 524dd3c2..b34b4e32 100644 --- a/packages/homebridge-ring/security-panel.ts +++ b/packages/homebridge-ring/security-panel.ts @@ -24,7 +24,7 @@ export class SecurityPanel extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/smoke-alarm.ts b/packages/homebridge-ring/smoke-alarm.ts index 7e38f79a..0d5c0c6b 100644 --- a/packages/homebridge-ring/smoke-alarm.ts +++ b/packages/homebridge-ring/smoke-alarm.ts @@ -8,7 +8,7 @@ export class SmokeAlarm extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/smoke-co-listener.ts b/packages/homebridge-ring/smoke-co-listener.ts index 37a13095..20c2b355 100644 --- a/packages/homebridge-ring/smoke-co-listener.ts +++ b/packages/homebridge-ring/smoke-co-listener.ts @@ -8,7 +8,7 @@ export class SmokeCoListener extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/switch.ts b/packages/homebridge-ring/switch.ts index 08d4eb2e..a5ce932c 100644 --- a/packages/homebridge-ring/switch.ts +++ b/packages/homebridge-ring/switch.ts @@ -9,7 +9,7 @@ export class Switch extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/temperature-sensor.ts b/packages/homebridge-ring/temperature-sensor.ts index 77fb7fca..6ef3a433 100644 --- a/packages/homebridge-ring/temperature-sensor.ts +++ b/packages/homebridge-ring/temperature-sensor.ts @@ -9,7 +9,7 @@ export class TemperatureSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -25,7 +25,7 @@ export class TemperatureSensor extends BaseDeviceAccessory { map((data) => { return data.celsius! }), - distinctUntilChanged() + distinctUntilChanged(), ), }) diff --git a/packages/homebridge-ring/thermostat.ts b/packages/homebridge-ring/thermostat.ts index cbfc2128..ab8e5d1b 100644 --- a/packages/homebridge-ring/thermostat.ts +++ b/packages/homebridge-ring/thermostat.ts @@ -14,7 +14,7 @@ export class Thermostat extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -25,24 +25,24 @@ export class Thermostat extends BaseDeviceAccessory { this.onTemperature = this.device.onComponentDevices.pipe( switchMap((devices) => { const temperatureSensor = devices.find( - ({ deviceType }) => deviceType === RingDeviceType.TemperatureSensor + ({ deviceType }) => deviceType === RingDeviceType.TemperatureSensor, ) if (!temperatureSensor) { return [] } logDebug( - `Discovered a component temperature sensor for ${this.device.name}` + `Discovered a component temperature sensor for ${this.device.name}`, ) return temperatureSensor.onData.pipe( map(({ celsius: temperature }) => { logDebug( - `Component temperature sensor for ${this.device.name} reported ${temperature} degrees` + `Component temperature sensor for ${this.device.name} reported ${temperature} degrees`, ) return temperature }), - distinctUntilChanged() + distinctUntilChanged(), ) - }) + }), ) // Required Characteristics @@ -59,7 +59,7 @@ export class Thermostat extends BaseDeviceAccessory { if (!temperature || !setPoint) { logError( - `Could not determine 'CurrentHeatingCoolingState' for ${this.device.name} given temperature: ${temperature}, set point: ${setPoint} and mode: ${mode}. Reporting 'off' state as a fallback.` + `Could not determine 'CurrentHeatingCoolingState' for ${this.device.name} given temperature: ${temperature}, set point: ${setPoint} and mode: ${mode}. Reporting 'off' state as a fallback.`, ) return Characteristic.CurrentHeatingCoolingState.OFF } @@ -91,7 +91,7 @@ export class Thermostat extends BaseDeviceAccessory { // but the current thermostat mode would only increase the difference, // so the thermostat is neither heating nor cooling return Characteristic.CurrentHeatingCoolingState.OFF - }) + }), ), }) @@ -126,7 +126,7 @@ export class Thermostat extends BaseDeviceAccessory { })() if (!mode) { logError( - `Couldn’t match ${targetHeatingCoolingState} to a recognized mode string.` + `Couldn’t match ${targetHeatingCoolingState} to a recognized mode string.`, ) return } @@ -154,14 +154,14 @@ export class Thermostat extends BaseDeviceAccessory { map((temperature) => { if (!temperature) { logError( - `Could not determine 'CurrentTemperature' for ${this.device.name} given temperature: ${temperature}. Returning 22 degrees celsius as a fallback.` + `Could not determine 'CurrentTemperature' for ${this.device.name} given temperature: ${temperature}. Returning 22 degrees celsius as a fallback.`, ) return 22 } // Documentation: https://developers.homebridge.io/#/characteristic/CurrentTemperature // 'Characteristic.CurrentTemperature' supports 0.1 increments return Number(Number(temperature).toFixed(1)) - }) + }), ), }) @@ -182,7 +182,7 @@ export class Thermostat extends BaseDeviceAccessory { if (setPoint < setPointMin || setPoint > setPointMax) { logError( - `Ignoring request to set ${this.device.name} target temperature to ${setPoint}. Target temperature must be between ${setPointMin} and ${setPointMax}.` + `Ignoring request to set ${this.device.name} target temperature to ${setPoint}. Target temperature must be between ${setPointMin} and ${setPointMax}.`, ) return } @@ -197,7 +197,7 @@ export class Thermostat extends BaseDeviceAccessory { const setPointMin = Math.max(this.device.data.setPointMin || 10, 10), setPointMax = Math.min(this.device.data.setPointMax || 38, 38) logDebug( - `Setting ${this.device.name} target temperature range to ${setPointMin}–${setPointMax}` + `Setting ${this.device.name} target temperature range to ${setPointMin}–${setPointMax}`, ) this.getService(Service.Thermostat) .getCharacteristic(Characteristic.TargetTemperature) diff --git a/packages/homebridge-ring/unknown-zwave-switch.ts b/packages/homebridge-ring/unknown-zwave-switch.ts index e25cb9ee..88cbfb8a 100644 --- a/packages/homebridge-ring/unknown-zwave-switch.ts +++ b/packages/homebridge-ring/unknown-zwave-switch.ts @@ -9,7 +9,7 @@ export class UnknownZWaveSwitchSwitch extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() diff --git a/packages/homebridge-ring/water-sensor.ts b/packages/homebridge-ring/water-sensor.ts index 8dd156fa..71a182c5 100644 --- a/packages/homebridge-ring/water-sensor.ts +++ b/packages/homebridge-ring/water-sensor.ts @@ -10,7 +10,7 @@ export class WaterSensor extends BaseDeviceAccessory { constructor( public readonly device: RingDevice, public readonly accessory: PlatformAccessory, - public readonly config: RingPlatformConfig + public readonly config: RingPlatformConfig, ) { super() @@ -24,7 +24,7 @@ export class WaterSensor extends BaseDeviceAccessory { ? LeakDetected.LEAK_DETECTED : LeakDetected.LEAK_NOT_DETECTED }), - distinctUntilChanged() + distinctUntilChanged(), ) this.initSensorService(leakService) diff --git a/packages/ring-client-api/api.ts b/packages/ring-client-api/api.ts index 8300e0b2..c157b74e 100644 --- a/packages/ring-client-api/api.ts +++ b/packages/ring-client-api/api.ts @@ -68,7 +68,7 @@ export class RingApi extends Subscribed { if (locationIds && !locationIds.length) { logError( - 'Your Ring config has `"locationIds": []`, which means no locations will be used and no devices will be found.' + 'Your Ring config has `"locationIds": []`, which means no locations will be used and no devices will be found.', ) } @@ -145,7 +145,7 @@ export class RingApi extends Subscribed { private listenForDeviceUpdates( cameras: RingCamera[], chimes: RingChime[], - intercoms: RingIntercom[] + intercoms: RingIntercom[], ) { const { cameraStatusPollingSeconds } = this.options if (!cameraStatusPollingSeconds) { @@ -153,24 +153,33 @@ export class RingApi extends Subscribed { } const devices = [...cameras, ...chimes, ...intercoms], onDeviceRequestUpdate = merge( - ...devices.map((device) => device.onRequestUpdate) + ...devices.map((device) => device.onRequestUpdate), ), onUpdateReceived = new Subject(), onPollForStatusUpdate = cameraStatusPollingSeconds ? onUpdateReceived.pipe(debounceTime(cameraStatusPollingSeconds * 1000)) : EMPTY, - camerasById = cameras.reduce((byId, camera) => { - byId[camera.id] = camera - return byId - }, {} as { [id: number]: RingCamera }), - chimesById = chimes.reduce((byId, chime) => { - byId[chime.id] = chime - return byId - }, {} as { [id: number]: RingChime }), - intercomsById = intercoms.reduce((byId, intercom) => { - byId[intercom.id] = intercom - return byId - }, {} as { [id: number]: RingIntercom }) + camerasById = cameras.reduce( + (byId, camera) => { + byId[camera.id] = camera + return byId + }, + {} as { [id: number]: RingCamera }, + ), + chimesById = chimes.reduce( + (byId, chime) => { + byId[chime.id] = chime + return byId + }, + {} as { [id: number]: RingChime }, + ), + intercomsById = intercoms.reduce( + (byId, intercom) => { + byId[intercom.id] = intercom + return byId + }, + {} as { [id: number]: RingIntercom }, + ) if (!cameras.length && !chimes.length && !intercoms.length) { return @@ -180,7 +189,7 @@ export class RingApi extends Subscribed { merge(onDeviceRequestUpdate, onPollForStatusUpdate) .pipe( throttleTime(500), - switchMap(() => this.fetchRingDevices().catch(() => null)) + switchMap(() => this.fetchRingDevices().catch(() => null)), ) .subscribe((response) => { onUpdateReceived.next(null) @@ -209,7 +218,7 @@ export class RingApi extends Subscribed { intercom.updateData(data) } }) - }) + }), ) if (cameraStatusPollingSeconds) { @@ -219,7 +228,7 @@ export class RingApi extends Subscribed { private async registerPushReceiver( cameras: RingCamera[], - intercoms: RingIntercom[] + intercoms: RingIntercom[], ) { const credentials = this.restClient._internalOnly_pushNotificationCredentials, @@ -272,7 +281,7 @@ export class RingApi extends Subscribed { } catch (e) { logError(e) } - }) + }), ) try { @@ -288,7 +297,7 @@ export class RingApi extends Subscribed { // These are likely duplicates, and we aren't currently storying persistent ids anywhere to avoid re-processing them if (Date.now() - startTime < 2000) { logInfo( - 'Ignoring push notification received in first two seconds after starting up' + 'Ignoring push notification received in first two seconds after starting up', ) return } @@ -297,7 +306,7 @@ export class RingApi extends Subscribed { try { const notification = JSONbig({ storeAsString: true }).parse( - dataJson + dataJson, ) as PushNotification if ('ding' in notification) { @@ -324,7 +333,7 @@ export class RingApi extends Subscribed { if (!rawLocations) { throw new Error( - 'The Ring account which you used to generate a refresh token does not have any associated locations. Please use an account that has access to at least one location.' + 'The Ring account which you used to generate a refresh token does not have any associated locations. Please use an account that has access to at least one location.', ) } @@ -349,7 +358,7 @@ export class RingApi extends Subscribed { intercoms, } = await this.fetchRingDevices(), locationIdsWithHubs = [...baseStations, ...beamBridges].map( - (x) => x.location_id + (x) => x.location_id, ), cameras = allCameras.map( (data) => @@ -359,12 +368,12 @@ export class RingApi extends Subscribed { authorizedDoorbots.includes(data as CameraData) || data.kind.startsWith('doorbell'), this.restClient, - this.options.avoidSnapshotBatteryDrain || false - ) + this.options.avoidSnapshotBatteryDrain || false, + ), ), ringChimes = chimes.map((data) => new RingChime(data, this.restClient)), ringIntercoms = intercoms.map( - (data) => new RingIntercom(data, this.restClient) + (data) => new RingIntercom(data, this.restClient), ), locations = rawLocations .filter((location) => { @@ -378,24 +387,24 @@ export class RingApi extends Subscribed { new Location( location, cameras.filter( - (x) => x.data.location_id === location.location_id + (x) => x.data.location_id === location.location_id, ), ringChimes.filter( - (x) => x.data.location_id === location.location_id + (x) => x.data.location_id === location.location_id, ), ringIntercoms.filter( - (x) => x.data.location_id === location.location_id + (x) => x.data.location_id === location.location_id, ), { hasHubs: locationIdsWithHubs.includes(location.location_id), hasAlarmBaseStation: baseStations.some( - (station) => station.location_id === location.location_id + (station) => station.location_id === location.location_id, ), locationModePollingSeconds: this.options.locationModePollingSeconds, }, - this.restClient - ) + this.restClient, + ), ) this.listenForDeviceUpdates(cameras, ringChimes, ringIntercoms) @@ -419,7 +428,7 @@ export class RingApi extends Subscribed { const locations = await this.getLocations() return locations.reduce( (cameras, location) => [...cameras, ...location.cameras], - [] as RingCamera[] + [] as RingCamera[], ) } @@ -437,7 +446,7 @@ export class RingApi extends Subscribed { this.getLocations() .then((locations) => - locations.forEach((location) => location.disconnect()) + locations.forEach((location) => location.disconnect()), ) .catch((e) => { logError(e) diff --git a/packages/ring-client-api/device-data.ts b/packages/ring-client-api/device-data.ts index 1f2dfd68..ea1a1c3b 100644 --- a/packages/ring-client-api/device-data.ts +++ b/packages/ring-client-api/device-data.ts @@ -55,10 +55,10 @@ function stripSensitiveFields(input: any) { export async function logDeviceData() { console.log( - 'This CLI will log data from you Ring Account to help debug issues and discovering new device types.' + 'This CLI will log data from you Ring Account to help debug issues and discovering new device types.', ) console.log( - 'The logged data is anonymized and should not compromise your account in any way.' + 'The logged data is anonymized and should not compromise your account in any way.', ) const refreshToken = await acquireRefreshToken(), diff --git a/packages/ring-client-api/location.ts b/packages/ring-client-api/location.ts index c638bd86..e29831c7 100644 --- a/packages/ring-client-api/location.ts +++ b/packages/ring-client-api/location.ts @@ -59,7 +59,7 @@ function flattenDeviceData(data: any): RingDeviceData { return Object.assign( {}, data.general && data.general.v2, - data.device && data.device.v1 + data.device && data.device.v1, ) } @@ -73,10 +73,10 @@ export class Location extends Subscribed { return message.datatype === 'DeviceInfoDocType' && Boolean(message.body) }), concatMap((message) => message.body), - map(flattenDeviceData) + map(flattenDeviceData), ) onDeviceList = this.onMessage.pipe( - filter((m) => m.msg === deviceListMessageType) + filter((m) => m.msg === deviceListMessageType), ) onDevices: Observable = this.onDeviceList.pipe( scan((devices, { body: deviceList, src }) => { @@ -105,15 +105,15 @@ export class Location extends Subscribed { return Boolean( this.assets && this.assets.every((asset) => - this.receivedAssetDeviceLists.includes(asset.uuid) - ) + this.receivedAssetDeviceLists.includes(asset.uuid), + ), ) }), - shareReplay(1) + shareReplay(1), ) onSessionInfo = this.onDataUpdate.pipe( filter((m) => m.msg === 'SessionInfo'), - map((m) => m.body as AssetSession[]) + map((m) => m.body as AssetSession[]), ) onConnected = new BehaviorSubject(false) onLocationMode = new ReplaySubject(1) @@ -138,7 +138,7 @@ export class Location extends Subscribed { hasAlarmBaseStation: boolean locationModePollingSeconds?: number }, - private restClient: RingRestClient + private restClient: RingRestClient, ) { super() @@ -165,25 +165,25 @@ export class Location extends Subscribed { // eslint-disable-next-line @typescript-eslint/no-empty-function this.requestList(deviceListMessageType, assetUuid).catch(() => {}) this.offlineAssets = this.offlineAssets.filter( - (id) => id !== assetUuid + (id) => id !== assetUuid, ) logInfo(`Ring ${asset.kind} ${assetUuid} has come back online`) } } else if (!assetWasOffline) { logError( - `Ring ${asset.kind} ${assetUuid} is offline or on cellular backup. Waiting for status to change` + `Ring ${asset.kind} ${assetUuid} is offline or on cellular backup. Waiting for status to change`, ) this.offlineAssets.push(assetUuid) } }) - }) + }), ) if (!options.hasAlarmBaseStation && options.locationModePollingSeconds) { this.addSubscriptions( merge(this.onLocationModeRequested, this.onLocationMode) .pipe(debounceTime(options.locationModePollingSeconds * 1000)) - .subscribe(() => this.getLocationMode()) + .subscribe(() => this.getLocationMode()), ) this.getLocationMode().catch(logError) @@ -211,7 +211,7 @@ export class Location extends Subscribed { if (process.version.startsWith('v15.')) { logError( - 'Node 15 is not currently supported by the Ring client. Please install the latest Node 14 instead. May not be able to fetch devices from Ring Alarm and Smart Lighting Hubs on this version of node.' + 'Node 15 is not currently supported by the Ring client. Please install the latest Node 14 instead. May not be able to fetch devices from Ring Alarm and Smart Lighting Hubs on this version of node.', ) } @@ -236,7 +236,7 @@ export class Location extends Subscribed { const connection = connectSocketIo( `wss://${host}/?authcode=${ticket}&ack=false&EIO=3`, - { transports: ['websocket'] } + { transports: ['websocket'] }, ), reconnect = () => { if (this.reconnecting && this.connectionPromise) { @@ -266,7 +266,7 @@ export class Location extends Subscribed { this.onDataUpdate.next(message) }) connection.on('message', (message: SocketIoMessage) => - this.onMessage.next(message) + this.onMessage.next(message), ) connection.on('error', reconnect) connection.on('disconnect', reconnect) @@ -276,7 +276,7 @@ export class Location extends Subscribed { this.onConnected.next(true) logInfo('Ring connected to socket.io server') assets.forEach((asset) => - this.requestList(deviceListMessageType, asset.uuid) + this.requestList(deviceListMessageType, asset.uuid), ) }) connection.once('error', reject) @@ -286,7 +286,7 @@ export class Location extends Subscribed { getConnection() { if (!this.hasHubs) { return Promise.reject( - new Error(`Location ${this.name} does not have any hubs`) + new Error(`Location ${this.name} does not have any hubs`), ) } @@ -311,7 +311,7 @@ export class Location extends Subscribed { async sendCommandToSecurityPanel( commandType: string, - data?: Record + data?: Record, ) { const securityPanel = await this.getSecurityPanel() securityPanel.sendCommand(commandType, data) @@ -330,7 +330,7 @@ export class Location extends Subscribed { if (updatedData.mode !== alarmMode) { throw new Error( - `Failed to set alarm mode to "${alarmMode}". Sensors may require bypass, which can only be done in the Ring app.` + `Failed to set alarm mode to "${alarmMode}". Sensors may require bypass, which can only be done in the Ring app.`, ) } } @@ -365,8 +365,8 @@ export class Location extends Subscribed { return firstValueFrom( this.onMessage.pipe( filter((m) => m.msg === type && m.src === src), - map((m) => m.body) - ) + map((m) => m.body), + ), ) } @@ -407,7 +407,7 @@ export class Location extends Subscribed { if (!securityPanel) { throw new Error( - `Could not find a security panel for location ${this.name} - ${this.id}` + `Could not find a security panel for location ${this.name} - ${this.id}`, ) } @@ -434,7 +434,7 @@ export class Location extends Subscribed { `rs/history${getSearchQueryString({ accountId: this.id, ...options, - })}` + })}`, ), }) } @@ -442,7 +442,7 @@ export class Location extends Subscribed { getCameraEvents(options: CameraEventOptions = {}) { return this.restClient.request({ url: clientApi( - `locations/${this.id}/events${getSearchQueryString(options)}` + `locations/${this.id}/events${getSearchQueryString(options)}`, ), }) } @@ -461,14 +461,14 @@ export class Location extends Subscribed { if (!baseStationAsset) { throw new Error( - 'Cannot dispatch panic events without an alarm base station' + 'Cannot dispatch panic events without an alarm base station', ) } return this.restClient.request({ method: 'POST', url: appApi( - `rs/monitoring/accounts/${this.id}/assets/${baseStationAsset.uuid}/userAlarm` + `rs/monitoring/accounts/${this.id}/assets/${baseStationAsset.uuid}/userAlarm`, ), json: { alarmSessionUuid, diff --git a/packages/ring-client-api/refresh-token.ts b/packages/ring-client-api/refresh-token.ts index 2fb1b5d0..76b74693 100755 --- a/packages/ring-client-api/refresh-token.ts +++ b/packages/ring-client-api/refresh-token.ts @@ -31,13 +31,13 @@ export async function acquireRefreshToken() { export async function logRefreshToken() { console.log( - 'This CLI will provide you with a refresh token which you can use to configure ring-client-api and homebridge-ring.' + 'This CLI will provide you with a refresh token which you can use to configure ring-client-api and homebridge-ring.', ) const refreshToken = await acquireRefreshToken() console.log( - '\nSuccessfully logged in to Ring. Please add the following to your config:\n' + '\nSuccessfully logged in to Ring. Please add the following to your config:\n', ) console.log(`"refreshToken": "${refreshToken}"`) } diff --git a/packages/ring-client-api/rest-client.ts b/packages/ring-client-api/rest-client.ts index 8d9b312c..ec35f99c 100644 --- a/packages/ring-client-api/rest-client.ts +++ b/packages/ring-client-api/rest-client.ts @@ -59,7 +59,7 @@ export interface ExtendedResponse { } async function requestWithRetry( - requestOptions: RequestOptions & { url: string; allowNoResponse?: boolean } + requestOptions: RequestOptions & { url: string; allowNoResponse?: boolean }, ): Promise { try { const options = { @@ -84,11 +84,11 @@ async function requestWithRetry( } catch (e: any) { if (!e.response && !requestOptions.allowNoResponse) { logError( - `Failed to reach Ring server at ${requestOptions.url}. ${e.message}. Trying again in 5 seconds...` + `Failed to reach Ring server at ${requestOptions.url}. ${e.message}. Trying again in 5 seconds...`, ) if (e.message.includes('NGHTTP2_ENHANCE_YOUR_CALM')) { logError( - `There is a known issue with your current NodeJS version (${process.version}). Please see https://github.com/dgreif/ring/wiki/NGHTTP2_ENHANCE_YOUR_CALM-Error for details` + `There is a known issue with your current NodeJS version (${process.version}). Please see https://github.com/dgreif/ring/wiki/NGHTTP2_ENHANCE_YOUR_CALM-Error for details`, ) } logDebug(e) @@ -164,11 +164,14 @@ export class RingRestClient { authPromise .then(({ expires_in }) => { // clear the existing auth promise 1 minute before it expires - const timeout = setTimeout(() => { - if (this._authPromise === authPromise) { - this.clearPreviousAuth() - } - }, ((expires_in || 3600) - 60) * 1000) + const timeout = setTimeout( + () => { + if (this._authPromise === authPromise) { + this.clearPreviousAuth() + } + }, + ((expires_in || 3600) - 60) * 1000, + ) this.timeouts.push(timeout) }) .catch(() => { @@ -193,7 +196,7 @@ export class RingRestClient { } constructor( - private authOptions: (EmailAuth | RefreshTokenAuth) & SessionOptions + private authOptions: (EmailAuth | RefreshTokenAuth) & SessionOptions, ) {} private getGrantData(twoFactorAuthCode?: string) { @@ -214,7 +217,7 @@ export class RingRestClient { } throw new Error( - 'Refresh token is not valid. Unable to authenticate with Ring servers. See https://github.com/dgreif/ring/wiki/Refresh-Tokens' + 'Refresh token is not valid. Unable to authenticate with Ring servers. See https://github.com/dgreif/ring/wiki/Refresh-Tokens', ) } @@ -300,7 +303,7 @@ export class RingRestClient { } throw new Error( - 'Your Ring account is configured to use 2-factor authentication (2fa). See https://github.com/dgreif/ring/wiki/Refresh-Tokens for details.' + 'Your Ring account is configured to use 2-factor authentication (2fa). See https://github.com/dgreif/ring/wiki/Refresh-Tokens for details.', ) } @@ -360,7 +363,7 @@ export class RingRestClient { : Number.parseInt(retryAfter, 10) logError( - `Session response rate limited. Waiting to retry after ${waitSeconds} seconds` + `Session response rate limited. Waiting to retry after ${waitSeconds} seconds`, ) await delay((waitSeconds + 1) * 1000) @@ -380,19 +383,24 @@ export class RingRestClient { private refreshSession() { this.sessionPromise = this.getSession() - this.sessionPromise.finally(() => { - // Refresh the session every 12 hours - // This is needed to keep the session alive for users outside the US, due to Data Residency laws - // We believe Ring is clearing the session info after ~24 hours, which breaks Push Notifications - const timeout = setTimeout(() => { - this.refreshSession() - }, 12 * 60 * 60 * 1000) // 12 hours - this.timeouts.push(timeout) - }) + this.sessionPromise + .finally(() => { + // Refresh the session every 12 hours + // This is needed to keep the session alive for users outside the US, due to Data Residency laws + // We believe Ring is clearing the session info after ~24 hours, which breaks Push Notifications + const timeout = setTimeout( + () => { + this.refreshSession() + }, + 12 * 60 * 60 * 1000, + ) // 12 hours + this.timeouts.push(timeout) + }) + .catch((e) => logError(e)) } async request( - options: RequestOptions & { url: string; allowNoResponse?: boolean } + options: RequestOptions & { url: string; allowNoResponse?: boolean }, ): Promise { const hardwareId = await this.hardwareIdPromise, url = options.url! as string, @@ -438,7 +446,7 @@ export class RingRestClient { if (errorText) { logError( - `http request failed. ${url} returned errors: (${errorText}). Trying again in 20 seconds` + `http request failed. ${url} returned errors: (${errorText}). Trying again in 20 seconds`, ) await delay(20000) @@ -446,8 +454,8 @@ export class RingRestClient { } logError( `http request failed. ${url} returned unknown errors: (${stringify( - errors - )}).` + errors, + )}).`, ) } @@ -455,7 +463,7 @@ export class RingRestClient { logError('404 from endpoint ' + url) if (response.body?.error?.includes(hardwareId)) { logError( - 'Session hardware_id not found. Creating a new session and trying again.' + 'Session hardware_id not found. Creating a new session and trying again.', ) if (this.sessionPromise === initialSessionPromise) { this.refreshSession() @@ -470,7 +478,7 @@ export class RingRestClient { logError( `Request to ${url} failed with status ${ response.statusCode - }. Response body: ${stringify(response.body)}` + }. Response body: ${stringify(response.body)}`, ) } else if (!options.allowNoResponse) { logError(`Request to ${url} failed:`) @@ -494,11 +502,11 @@ export class RingRestClient { } set _internalOnly_pushNotificationCredentials( - credentials: Credentials | undefined + credentials: Credentials | undefined, ) { if (!this.refreshToken || !this.authConfig) { throw new Error( - 'Cannot set push notification credentials without a refresh token' + 'Cannot set push notification credentials without a refresh token', ) } diff --git a/packages/ring-client-api/ring-camera.ts b/packages/ring-client-api/ring-camera.ts index af1e6400..8b7c4d5e 100644 --- a/packages/ring-client-api/ring-camera.ts +++ b/packages/ring-client-api/ring-camera.ts @@ -71,7 +71,7 @@ function getEndOfToday() { export function getBatteryLevel( data: Pick & { health?: Partial - } + }, ) { const levels = [ parseBatteryLife(data.battery_life), @@ -90,7 +90,7 @@ export function getBatteryLevel( } export function getSearchQueryString( - options: CameraEventOptions | (HistoryOptions & { accountId: string }) + options: CameraEventOptions | (HistoryOptions & { accountId: string }), ) { const queryString = Object.entries(options) .map(([key, value]) => { @@ -131,24 +131,24 @@ export class RingCamera extends Subscribed { onActiveNotifications = new BehaviorSubject([]) onDoorbellPressed = this.onNewNotification.pipe( filter( - (notification) => notification.action === PushNotificationAction.Ding + (notification) => notification.action === PushNotificationAction.Ding, ), - share() + share(), ) onMotionDetected = this.onActiveNotifications.pipe( map((notifications) => notifications.some( - (notification) => notification.action === PushNotificationAction.Motion - ) + (notification) => notification.action === PushNotificationAction.Motion, + ), ), distinctUntilChanged(), publishReplay(1), - refCount() + refCount(), ) onMotionStarted = this.onMotionDetected.pipe( filter((currentlyDetected) => currentlyDetected), mapTo(null), // no value needed, event is what matters - share() + share(), ) onBatteryLevel onInHomeDoorbellStatus @@ -157,7 +157,7 @@ export class RingCamera extends Subscribed { private initialData: AnyCameraData, public isDoorbot: boolean, private restClient: RingRestClient, - private avoidSnapshotBatteryDrain: boolean + private avoidSnapshotBatteryDrain: boolean, ) { super() @@ -177,13 +177,13 @@ export class RingCamera extends Subscribed { } return getBatteryLevel(data) }), - distinctUntilChanged() + distinctUntilChanged(), ) this.onInHomeDoorbellStatus = this.onData.pipe( map(({ settings: { chime_settings } }: AnyCameraData) => { return Boolean(chime_settings?.enable) }), - distinctUntilChanged() + distinctUntilChanged(), ) this.addSubscriptions( @@ -194,7 +194,7 @@ export class RingCamera extends Subscribed { logError( 'Failed to subscribe ' + initialData.description + - ' to ding events' + ' to ding events', ) logError(e) }) @@ -203,11 +203,11 @@ export class RingCamera extends Subscribed { logError( 'Failed to subscribe ' + initialData.description + - ' to motion events' + ' to motion events', ) logError(e) }) - }) + }), ) } @@ -283,8 +283,8 @@ export class RingCamera extends Subscribed { Boolean( chime_settings && [DoorbellType.Mechanical, DoorbellType.Digital].includes( - chime_settings.type - ) + chime_settings.type, + ), ) ) } @@ -413,7 +413,7 @@ export class RingCamera extends Subscribed { dingId = notification.ding.id this.onActiveNotifications.next( - activeDings.filter((d) => d.ding.id !== dingId).concat([notification]) + activeDings.filter((d) => d.ding.id !== dingId).concat([notification]), ) this.onNewNotification.next(notification) @@ -427,7 +427,7 @@ export class RingCamera extends Subscribed { url: clientApi( `locations/${this.data.location_id}/devices/${ this.id - }/events${getSearchQueryString(options)}` + }/events${getSearchQueryString(options)}`, ), }) } @@ -436,11 +436,11 @@ export class RingCamera extends Subscribed { { dateFrom, dateTo, order = 'asc' } = { dateFrom: getStartOfToday(), dateTo: getEndOfToday(), - } + }, ) { return this.restClient.request({ url: clientApi( - `video_search/history?doorbot_id=${this.id}&date_from=${dateFrom}&date_to=${dateTo}&order=${order}&api_version=11&includes%5B%5D=pva` + `video_search/history?doorbot_id=${this.id}&date_from=${dateFrom}&date_to=${dateTo}&order=${order}&api_version=11&includes%5B%5D=pva`, ), }) } @@ -449,7 +449,7 @@ export class RingCamera extends Subscribed { { startAtMs, endAtMs } = { startAtMs: getStartOfToday(), endAtMs: getEndOfToday(), - } + }, ) { // These will be mp4 clips that are created using periodic snapshots return this.restClient.request({ @@ -493,13 +493,13 @@ export class RingCamera extends Subscribed { private checkIfSnapshotsAreBlocked() { if (this.snapshotsAreBlocked) { throw new Error( - `Motion detection is disabled for ${this.name}, which prevents snapshots from this camera. This can be caused by Modes settings or by turning off the Record Motion setting.` + `Motion detection is disabled for ${this.name}, which prevents snapshots from this camera. This can be caused by Modes settings or by turning off the Record Motion setting.`, ) } if (this.isOffline) { throw new Error( - `Cannot fetch snapshot for ${this.name} because it is offline` + `Cannot fetch snapshot for ${this.name} because it is offline`, ) } } @@ -513,7 +513,7 @@ export class RingCamera extends Subscribed { logDebug( `Snapshot for ${this.name} is still within its life time (${ this.currentTimestampAge / 1000 - }s old)` + }s old)`, ) return true } @@ -540,14 +540,14 @@ export class RingCamera extends Subscribed { : { afterMs: this.lastSnapshotTimestamp, force: true, - } + }, ), delay(maxSnapshotRefreshSeconds * 1000).then(() => { const extraMessageForBatteryCam = this.operatingOnBattery ? '. This is normal behavior since this camera is unable to capture snapshots while streaming' : '' throw new Error( - `Snapshot for ${this.name} (${this.deviceType} - ${this.model}) failed to refresh after ${maxSnapshotRefreshSeconds} seconds${extraMessageForBatteryCam}` + `Snapshot for ${this.name} (${this.deviceType} - ${this.model}) failed to refresh after ${maxSnapshotRefreshSeconds} seconds${extraMessageForBatteryCam}`, ) }), ]) diff --git a/packages/ring-client-api/ring-chime.ts b/packages/ring-client-api/ring-chime.ts index 368c6354..7ee8196f 100644 --- a/packages/ring-client-api/ring-chime.ts +++ b/packages/ring-client-api/ring-chime.ts @@ -25,7 +25,7 @@ export class RingChime { constructor( private initialData: ChimeData, - private restClient: RingRestClient + private restClient: RingRestClient, ) { this.id = this.initialData.id this.deviceType = this.initialData.kind @@ -69,7 +69,7 @@ export class RingChime { (audio) => audio.available && audio.description === description && - audio.kind === kind + audio.kind === kind, ) if (!requestedRingtone) { @@ -122,14 +122,14 @@ export class RingChime { // inform caller if this change requires a reboot return Object.keys(update.settings || {}).some((key) => - settingsWhichRequireReboot.includes(key) + settingsWhichRequireReboot.includes(key), ) } setVolume(volume: number) { if (volume < 0 || volume > 11) { throw new Error( - `Volume for ${this.name} must be between 0 and 11, got ${volume}` + `Volume for ${this.name} must be between 0 and 11, got ${volume}`, ) } diff --git a/packages/ring-client-api/ring-device.ts b/packages/ring-client-api/ring-device.ts index 2ed06990..629c53b5 100644 --- a/packages/ring-client-api/ring-device.ts +++ b/packages/ring-client-api/ring-device.ts @@ -16,7 +16,7 @@ export class RingDevice extends Subscribed { constructor( private initialData: RingDeviceData, public location: Location, - public assetId: string + public assetId: string, ) { super() @@ -26,13 +26,15 @@ export class RingDevice extends Subscribed { this.deviceType = this.initialData.deviceType this.categoryId = this.initialData.categoryId this.onComponentDevices = this.location.onDevices.pipe( - map((devices) => devices.filter(({ data }) => data.parentZid === this.id)) + map((devices) => + devices.filter(({ data }) => data.parentZid === this.id), + ), ) this.addSubscriptions( location.onDeviceDataUpdate .pipe(filter((update) => update.zid === this.zid)) - .subscribe((update) => this.updateData(update)) + .subscribe((update) => this.updateData(update)), ) } @@ -62,7 +64,7 @@ export class RingDevice extends Subscribed { if (!this.supportsVolume) { throw new Error( - `Volume can only be set on ${deviceTypesWithVolume.join(', ')}` + `Volume can only be set on ${deviceTypesWithVolume.join(', ')}`, ) } @@ -106,7 +108,7 @@ export class RingDevice extends Subscribed { data: this.data, }, null, - 2 + 2, ) } diff --git a/packages/ring-client-api/ring-intercom.ts b/packages/ring-client-api/ring-intercom.ts index 1ce20725..4aede239 100644 --- a/packages/ring-client-api/ring-intercom.ts +++ b/packages/ring-client-api/ring-intercom.ts @@ -20,23 +20,23 @@ export class RingIntercom { constructor( private initialData: IntercomHandsetAudioData, - private restClient: RingRestClient + private restClient: RingRestClient, ) { this.id = this.initialData.id this.deviceType = this.initialData.kind this.onData = new BehaviorSubject( - this.initialData + this.initialData, ) this.onBatteryLevel = this.onData.pipe( map((data) => getBatteryLevel(data)), - distinctUntilChanged() + distinctUntilChanged(), ) if (!initialData.subscribed) { this.subscribeToDingEvents().catch((e) => { logError( - 'Failed to subscribe ' + initialData.description + ' to ding events' + 'Failed to subscribe ' + initialData.description + ' to ding events', ) logError(e) }) diff --git a/packages/ring-client-api/ring-types.ts b/packages/ring-client-api/ring-types.ts index 88f92b3b..c135efbd 100644 --- a/packages/ring-client-api/ring-types.ts +++ b/packages/ring-client-api/ring-types.ts @@ -22,6 +22,7 @@ export enum RingDeviceType { CoAlarm = 'alarm.co', SmokeCoListener = 'listener.smoke-co', MultiLevelSwitch = 'switch.multilevel', + // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values Fan = 'switch.multilevel', MultiLevelBulb = 'switch.multilevel.bulb', Switch = 'switch', @@ -36,9 +37,12 @@ export enum RingDeviceType { Thermostat = 'temperature-control.thermostat', Sensor = 'sensor', RingNetAdapter = 'adapter.ringnet', + // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values CodeVault = 'access-code.vault', + // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values SecurityAccessCode = 'access-code', ZWaveAdapter = 'adapter.zwave', + // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values ZWaveExtender = 'range-extender.zwave', PanicButton = 'security-panic', UnknownZWave = 'unknown.zwave', @@ -381,7 +385,7 @@ export interface RingtoneOptions { url: string checksum: string available: string - } + }, ] } diff --git a/packages/ring-client-api/streaming/peer-connection.ts b/packages/ring-client-api/streaming/peer-connection.ts index bc725da3..b4816e5d 100644 --- a/packages/ring-client-api/streaming/peer-connection.ts +++ b/packages/ring-client-api/streaming/peer-connection.ts @@ -126,7 +126,7 @@ export class WeriftPeerConnection videoTransceiver.receiver .sendRtcpPLI(track.ssrc!) .catch((e) => logError(e)) - }) + }), ) this.requestKeyFrame() }) diff --git a/packages/ring-client-api/streaming/simple-webrtc-session.ts b/packages/ring-client-api/streaming/simple-webrtc-session.ts index 742ec2bc..fa868453 100644 --- a/packages/ring-client-api/streaming/simple-webrtc-session.ts +++ b/packages/ring-client-api/streaming/simple-webrtc-session.ts @@ -11,7 +11,7 @@ export class SimpleWebRtcSession { constructor( private readonly camera: RingCamera, - private restClient: RingRestClient + private restClient: RingRestClient, ) {} async start(sdp: string): Promise { diff --git a/packages/ring-client-api/streaming/streaming-session.ts b/packages/ring-client-api/streaming/streaming-session.ts index 899c04bc..64beab6f 100644 --- a/packages/ring-client-api/streaming/streaming-session.ts +++ b/packages/ring-client-api/streaming/streaming-session.ts @@ -41,7 +41,7 @@ export class StreamingSession extends Subscribed { constructor( private readonly camera: RingCamera, - private connection: WebrtcConnection + private connection: WebrtcConnection, ) { super() @@ -55,7 +55,7 @@ export class StreamingSession extends Subscribed { connection.onCallAnswered.subscribe((sdp) => { this.onUsingOpus.next(sdp.toLocaleLowerCase().includes(' opus/')) }), - connection.onCallEnded.subscribe(() => this.callEnded()) + connection.onCallEnded.subscribe(() => this.callEnded()), ) } @@ -88,10 +88,10 @@ export class StreamingSession extends Subscribed { this.connection.onError.pipe( map((e) => { throw e - }) - ) - ) - ) + }), + ), + ), + ), ) } @@ -135,7 +135,7 @@ export class StreamingSession extends Subscribed { ...(transcodeVideoStream ? ffmpegOptions.video || ['-vcodec', 'copy'] : []), - ...(ffmpegOptions.output || []) + ...(ffmpegOptions.output || []), ), ffmpegPath: getFfmpegPath(), exitCallback: () => this.callEnded(), @@ -153,9 +153,9 @@ export class StreamingSession extends Subscribed { return this.audioSplitter.send(rtp.serialize(), { port: audioPort, }) - }) + }), ) - .subscribe() + .subscribe(), ) if (transcodeVideoStream) { @@ -166,9 +166,9 @@ export class StreamingSession extends Subscribed { return this.videoSplitter.send(rtp.serialize(), { port: videoPort, }) - }) + }), ) - .subscribe() + .subscribe(), ) } diff --git a/packages/ring-client-api/streaming/webrtc-connection.ts b/packages/ring-client-api/streaming/webrtc-connection.ts index f84d8f9a..ef606eb6 100644 --- a/packages/ring-client-api/streaming/webrtc-connection.ts +++ b/packages/ring-client-api/streaming/webrtc-connection.ts @@ -35,7 +35,7 @@ export class WebrtcConnection extends Subscribed { constructor( ticket: string, private camera: RingCamera, - options: StreamingConnectionOptions + options: StreamingConnectionOptions, ) { super() this.ws = new WebSocket( @@ -45,7 +45,7 @@ export class WebrtcConnection extends Subscribed { // This must exist or the socket will close immediately but content does not seem to matter 'User-Agent': 'android:com.ringapp', }, - } + }, ) if (options.createPeerConnection) { @@ -80,13 +80,13 @@ export class WebrtcConnection extends Subscribed { e.message.includes('negotiate codecs failed') ) { e = new Error( - 'Failed to negotiate codecs. This is a known issue with Ring cameras. Please see https://github.com/dgreif/ring/wiki/Streaming-Legacy-Mode' + 'Failed to negotiate codecs. This is a known issue with Ring cameras. Please see https://github.com/dgreif/ring/wiki/Streaming-Legacy-Mode', ) } this.onError.next(e) throw e }) - }) + }), ) .subscribe(), @@ -141,7 +141,7 @@ export class WebrtcConnection extends Subscribed { mlineindex: iceCandidate.sdpMLineIndex, }, }) - }) + }), ) } @@ -243,7 +243,7 @@ export class WebrtcConnection extends Subscribed { } else { // Otherwise wait for the session id to be set and then send the message this.addSubscriptions( - this.onSessionId.pipe(take(1)).subscribe(sendSessionMessage) + this.onSessionId.pipe(take(1)).subscribe(sendSessionMessage), ) } } @@ -264,7 +264,7 @@ export class WebrtcConnection extends Subscribed { this.pc.returnAudioTrack.writeRtp(rtp) } else { throw new Error( - 'Cannot send audio packets to a custom peer connection implementation' + 'Cannot send audio packets to a custom peer connection implementation', ) } } @@ -286,7 +286,7 @@ export class WebrtcConnection extends Subscribed { this.sendSessionMessage('camera_options', { stealth_mode: false, }) - }) + }), ) } diff --git a/packages/ring-client-api/test/rest-client.spec.ts b/packages/ring-client-api/test/rest-client.spec.ts index 68f93390..1ce698fa 100644 --- a/packages/ring-client-api/test/rest-client.spec.ts +++ b/packages/ring-client-api/test/rest-client.spec.ts @@ -32,7 +32,7 @@ const email = 'some@one.com', error: 'Invalid auth headers: ' + JSON.stringify(req.headers.raw(), null, 2), - }) + }), ) } @@ -47,7 +47,7 @@ const email = 'some@one.com', refresh_token: secondRefreshToken, scope: 'client', token_type: 'Bearer', - }) + }), ) } @@ -61,7 +61,7 @@ const email = 'some@one.com', refresh_token: thirdRefreshToken, scope: 'client', token_type: 'Bearer', - }) + }), ) } @@ -71,7 +71,7 @@ const email = 'some@one.com', ctx.json({ error: 'invalid_grant', error_description: 'token is invalid or does not exists', - }) + }), ) } @@ -85,7 +85,7 @@ const email = 'some@one.com', ctx.json({ code: 1, error: 'Invalid auth request: ' + JSON.stringify(body), - }) + }), ) } @@ -96,7 +96,7 @@ const email = 'some@one.com', ctx.json({ error: 'access_denied', error_description: 'invalid user credentials', - }) + }), ) } @@ -110,7 +110,7 @@ const email = 'some@one.com', ctx.json({ err_msg: 'bad request response from dependency service', error: 'Verification Code is invalid or expired', - }) + }), ) } @@ -124,7 +124,7 @@ const email = 'some@one.com', scope: 'client', token_type: 'Bearer', responseTimestamp: Date.now(), - }) + }), ) } @@ -135,7 +135,7 @@ const email = 'some@one.com', next_time_in_secs: 60, phone, tsv_state: 'sms', - }) + }), ) }), rest.post( @@ -160,7 +160,7 @@ const email = 'some@one.com', ) { return res( ctx.status(400), - ctx.body('Bad session request: ' + JSON.stringify(body, null, 2)) + ctx.body('Bad session request: ' + JSON.stringify(body, null, 2)), ) } @@ -171,10 +171,10 @@ const email = 'some@one.com', profile: { id: 1234, }, - }) + }), ) - } - ) + }, + ), ) async function wrapRefreshToken(rt: string) { @@ -182,7 +182,7 @@ async function wrapRefreshToken(rt: string) { JSON.stringify({ rt, hid: await hardwareIdPromise, - }) + }), ) } @@ -214,11 +214,11 @@ describe('getAuth', () => { }) await expect(() => client.getAuth()).rejects.toThrow( - 'Your Ring account is configured to use 2-factor authentication (2fa). See https://github.com/dgreif/ring/wiki/Refresh-Tokens for details.' + 'Your Ring account is configured to use 2-factor authentication (2fa). See https://github.com/dgreif/ring/wiki/Refresh-Tokens for details.', ) expect(client.promptFor2fa).toEqual( - `Please enter the code sent to ${phone} via sms` + `Please enter the code sent to ${phone} via sms`, ) expect(client.using2fa).toEqual(true) }) @@ -248,7 +248,7 @@ describe('getAuth', () => { }) await expect(() => client.getAuth()).rejects.toThrow( - 'Failed to fetch oauth token from Ring. Verify that your email and password are correct. (error: access_denied)' + 'Failed to fetch oauth token from Ring. Verify that your email and password are correct. (error: access_denied)', ) }) @@ -263,10 +263,10 @@ describe('getAuth', () => { // call getAuth again with an invalid 2fa code, which should fail await expect(() => client.getAuth('invalid 2fa code')).rejects.toThrow( - 'Verification Code is invalid or expired' + 'Verification Code is invalid or expired', ) expect(client.promptFor2fa).toEqual( - 'Invalid 2fa code entered. Please try again.' + 'Invalid 2fa code entered. Please try again.', ) }) @@ -280,7 +280,7 @@ describe('getAuth', () => { refresh_token: await wrapRefreshToken(secondRefreshToken), }) expect(client.refreshToken).toEqual( - await wrapRefreshToken(secondRefreshToken) + await wrapRefreshToken(secondRefreshToken), ) }) @@ -334,13 +334,13 @@ describe('fetch', () => { ctx.json({ error: 'Session not found for ' + req.headers.get('hardware_id'), - }) + }), ) } return res(ctx.json([])) - } - ) + }, + ), ) }) diff --git a/packages/ring-client-api/test/ring-camera.spec.ts b/packages/ring-client-api/test/ring-camera.spec.ts index 38ad0488..baadadf5 100644 --- a/packages/ring-client-api/test/ring-camera.spec.ts +++ b/packages/ring-client-api/test/ring-camera.spec.ts @@ -6,7 +6,7 @@ describe('Ring Camera', () => { expect( getBatteryLevel({ battery_life: '49', - }) + }), ).toEqual(49) }) @@ -16,22 +16,22 @@ describe('Ring Camera', () => { it('should handle right battery only', () => { expect( - getBatteryLevel({ battery_life: null, battery_life_2: 24 }) + getBatteryLevel({ battery_life: null, battery_life_2: 24 }), ).toEqual(24) }) it('should handle left battery only', () => { expect( - getBatteryLevel({ battery_life: 76, battery_life_2: null }) + getBatteryLevel({ battery_life: 76, battery_life_2: null }), ).toEqual(76) }) it('should handle dual batteries', () => { expect( - getBatteryLevel({ battery_life: '92', battery_life_2: 84 }) + getBatteryLevel({ battery_life: '92', battery_life_2: 84 }), ).toEqual(84) expect( - getBatteryLevel({ battery_life: '92', battery_life_2: 100 }) + getBatteryLevel({ battery_life: '92', battery_life_2: 100 }), ).toEqual(92) }) }) @@ -39,13 +39,13 @@ describe('Ring Camera', () => { describe('cleanSnapshotUuid', () => { it('should return the original uuid if it is already clean', () => { expect(cleanSnapshotUuid('c2a0a397-3538-422d-bb4e-51837a56b870')).toBe( - 'c2a0a397-3538-422d-bb4e-51837a56b870' + 'c2a0a397-3538-422d-bb4e-51837a56b870', ) }) it('should return remove anything after :', () => { expect( - cleanSnapshotUuid('c2a0a397-3538-422d-bb4e-51837a56b870:122429140') + cleanSnapshotUuid('c2a0a397-3538-422d-bb4e-51837a56b870:122429140'), ).toBe('c2a0a397-3538-422d-bb4e-51837a56b870') }) diff --git a/packages/ring-client-api/util.ts b/packages/ring-client-api/util.ts index fbf29945..cd4fac59 100644 --- a/packages/ring-client-api/util.ts +++ b/packages/ring-client-api/util.ts @@ -83,7 +83,7 @@ export async function getHardwareId(systemId?: string) { if (id === timeoutValue) { logError( - 'Request for system uuid timed out. Falling back to random session id' + 'Request for system uuid timed out. Falling back to random session id', ) return generateRandomUuid() } @@ -125,7 +125,7 @@ export function stringify(data: any) { export function mapAsync( records: T[], - asyncMapper: (record: T) => Promise + asyncMapper: (record: T) => Promise, ): Promise { return Promise.all(records.map((record) => asyncMapper(record))) }