Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Commit

Permalink
fix alerts for users without Nest Aware
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandawg93 committed Aug 3, 2020
1 parent 2bb37a6 commit d8a535d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 63 deletions.
83 changes: 44 additions & 39 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {
PlatformConfig,
} from 'homebridge';
import { NestCam } from './nest-cam';
import { CameraInfo, ModelTypes, Properties } from './camera-info';
import { NestStructure } from './nest-structure';
import { CameraInfo, ModelTypes, Properties } from './models/camera-info';
import { Face } from './models/structure-info';
import { NestEndpoints, handleError } from './nest-endpoints';
import { StreamingDelegate } from './streaming-delegate';
import { Connection } from './nest-connection';
Expand All @@ -33,6 +35,7 @@ class NestCamPlatform implements DynamicPlatformPlugin {
private endpoints: NestEndpoints = new NestEndpoints(false);
private readonly accessories: Array<PlatformAccessory> = [];
private readonly cameras: Array<NestCam> = [];
private readonly nestStructures: Record<string, NestStructure> = {};
private motionDetection = true;
private doorbellAlerts = true;
private doorbellSwitch = true;
Expand Down Expand Up @@ -142,13 +145,18 @@ class NestCamPlatform implements DynamicPlatformPlugin {
service && service.updateCharacteristic(hap.Characteristic.On, camera.info.properties[_key]);
}

private createMotionService(name: string, canCreate: boolean, accessory: PlatformAccessory, camera: NestCam) {
const service = accessory.getService(`${accessory.displayName} ${name}`);
private createMotionService(
name: string,
canCreate: boolean,
accessory: PlatformAccessory | undefined,
camera: NestCam,
) {
const service = accessory?.getService(`${accessory.displayName} ${name}`);
if (service) {
accessory.removeService(service);
accessory?.removeService(service);
}
if (canCreate) {
accessory.addService(
accessory?.addService(
new hap.Service.MotionSensor(`${accessory.displayName} ${name}`, `${accessory.displayName} ${name}`),
);
camera.startAlertChecks();
Expand Down Expand Up @@ -327,43 +335,40 @@ class NestCamPlatform implements DynamicPlatformPlugin {
this.cameras.forEach(async (camera) => {
const uuid = hap.uuid.generate(camera.info.uuid);
const accessory = this.accessories.find((x: PlatformAccessory) => x.UUID === uuid);
if (accessory) {
// Motion configuration
if (camera.info.full_camera_enabled) {
if (camera.info.capabilities.includes('stranger_detection')) {
const useFaces = camera.alertTypes.includes('Face');
const index = camera.alertTypes.indexOf('Face');
if (index > -1) {
camera.alertTypes.splice(index, 1);
}
if (useFaces) {
const faces = await camera.getFaces();
if (faces) {
faces.forEach((face: any) => {
camera.alertTypes.push(`Face - ${face.name}`);
});
}
}
} else {
camera.alertTypes = ['Motion', 'Sound', 'Person'];
// Motion configuration
if (camera.info.capabilities.includes('stranger_detection')) {
const useFaces = camera.alertTypes.includes('Face');
const index = camera.alertTypes.indexOf('Face');
if (index > -1) {
camera.alertTypes.splice(index, 1);
}
if (useFaces) {
const structureId = camera.info.nest_structure_id.replace('structure.', '');
let structure = this.nestStructures[structureId];
if (!structure) {
structure = new NestStructure(camera.info, this.config, this.log);
this.nestStructures[structureId] = structure;
}
const faces = await structure.getFaces();
if (faces) {
faces.forEach((face: Face) => {
camera.alertTypes.push(`Face - ${face.name}`);
});
}
camera.alertTypes.forEach((type) => {
this.createMotionService(
type,
camera.info.capabilities.includes('detectors.on_camera') && this.motionDetection,
accessory,
camera,
);
});
} else {
this.createMotionService(
'Motion',
camera.info.capabilities.includes('detectors.on_camera') && this.motionDetection,
accessory,
camera,
);
}
} else {
// Remove 'Package Delivered', 'Package Retrieved', 'Face'
const remove = ['Package Delivered', 'Package Retrieved', 'Face'];
camera.alertTypes = camera.alertTypes.filter((x) => !remove.includes(x));
}
camera.alertTypes.forEach((type) => {
this.createMotionService(
type,
camera.info.capabilities.includes('detectors.on_camera') && this.motionDetection,
accessory,
camera,
);
});
});
}

Expand Down
33 changes: 9 additions & 24 deletions src/nest-cam.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HAP, Logging, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
import { NestEndpoints, handleError } from './nest-endpoints';
import { CameraInfo, Properties } from './camera-info';
import { CameraInfo, Properties } from './models/camera-info';
import querystring from 'querystring';
import { EventEmitter } from 'events';

Expand Down Expand Up @@ -45,7 +45,7 @@ export class NestCam extends EventEmitter {
public alertTypes: Array<string> = [];
private alertCooldown = 180000;
private alertInterval = 10000;
private alertTimeout: NodeJS.Timeout | undefined;
private alertTimeout: NodeJS.Timeout | undefined | number;
private alertFailures = 0;
private alertsSend = true;

Expand Down Expand Up @@ -129,12 +129,12 @@ export class NestCam extends EventEmitter {
}

stopAlertChecks() {
if (this.alertTimeout) {
if (this.alertTimeout && typeof this.alertTimeout == 'number') {
clearInterval(this.alertTimeout);
}
}

private async checkAlerts(): Promise<void> {
public async checkAlerts(): Promise<void> {
if (!this.alertsSend) {
return;
}
Expand Down Expand Up @@ -169,7 +169,11 @@ export class NestCam extends EventEmitter {
}

if (trigger.is_important && !this.motionDetected) {
this.triggerMotion(trigger.types);
if (trigger.types && trigger.types.length > 0) {
this.triggerMotion(trigger.types);
} else {
this.triggerMotion(['Motion']);
}
break;
}
}
Expand Down Expand Up @@ -239,23 +243,4 @@ export class NestCam extends EventEmitter {
);
}
}

async getFaces(): Promise<Array<any>> {
try {
if (!this.accessory.context.removed) {
const response = await this.endpoints.sendRequest(
this.config.access_token,
`https://${this.info.nexus_api_nest_domain_host}`,
`/faces/${this.info.nest_structure_id.replace('structure.', '')}`,
'GET',
);
if (response && response.length > 0) {
return response;
}
}
} catch (error) {
handleError(this.log, error, 'Error getting faces');
}
return [];
}
}

0 comments on commit d8a535d

Please sign in to comment.