homebridge-nest-cam-ft
Version:
Nest cam plugin for homebridge: https://homebridge.io/
183 lines • 8.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NestAccessory = void 0;
const streaming_delegate_1 = require("./streaming-delegate");
const sanitizeString = (str) => {
if (str.includes('package')) {
return str.replace('-', ' ').replace(/(?:^|\s|["'([{])+\S/g, (match) => match.toUpperCase());
}
else if (str.startsWith('Face') || str.startsWith('Zone')) {
return str;
}
else {
return str.replace(/(?:^|\s|["'([{])+\S/g, (match) => match.toUpperCase());
}
};
class NestAccessory {
constructor(accessory, camera, config, log, hap) {
this.accessory = accessory;
this.camera = camera;
this.config = config;
this.log = log;
this.hap = hap;
camera.on("camera-change", (value) => {
const service = this.accessory.getService(`${this.accessory.displayName} Streaming`);
service && service.updateCharacteristic(this.hap.Characteristic.On, value);
});
camera.on("chime-change", (value) => {
const service = this.accessory.getService(`${this.accessory.displayName} Chime`);
service && service.updateCharacteristic(this.hap.Characteristic.On, value);
});
camera.on("chime-assist-change", (value) => {
const service = this.accessory.getService(`${this.accessory.displayName} Announcements`);
service && service.updateCharacteristic(this.hap.Characteristic.On, value);
});
camera.on("audio-change", (value) => {
const service = this.accessory.getService(`${this.accessory.displayName} Audio`);
service && service.updateCharacteristic(this.hap.Characteristic.On, value);
});
camera.on("motion-detected", (state, alertTypes) => {
this.setMotion(state, alertTypes);
});
camera.on("doorbell-rang", () => {
this.setDoorbell();
});
}
createService(serviceType, name) {
const existingService = name
? this.accessory.getServiceById(serviceType, `${this.accessory.displayName} ${name}`)
: this.accessory.getService(serviceType);
const service = existingService ||
(name
? this.accessory.addService(serviceType, `${this.accessory.displayName} ${name}`, `${this.accessory.displayName} ${name}`)
: this.accessory.addService(serviceType, this.accessory.displayName));
return service;
}
removeService(serviceType, name) {
const existingService = name
? this.accessory.getServiceById(serviceType, `${this.accessory.displayName} ${name}`)
: this.accessory.getService(serviceType);
if (existingService) {
this.accessory.removeService(existingService);
}
}
removeAllServicesByType(serviceType) {
let existingService = this.accessory.getService(serviceType);
while (existingService) {
this.accessory.removeService(existingService);
existingService = this.accessory.getService(serviceType);
}
}
createSwitchService(name, serviceType, _key, cb) {
const service = this.createService(serviceType, name);
this.log.debug(`Creating switch for ${this.accessory.displayName} ${name}.`);
service
.setCharacteristic(this.hap.Characteristic.On, this.camera.info.properties[_key])
.getCharacteristic(this.hap.Characteristic.On)
.on("set", (value, callback) => {
cb(value);
this.log.info(`Setting ${this.accessory.displayName} ${name} to ${value ? 'on' : 'off'}`);
callback();
})
.on("get", (callback) => {
callback(undefined, this.camera.info.properties[_key]);
});
}
configureController() {
const streamingDelegate = new streaming_delegate_1.StreamingDelegate(this.hap, this.camera, this.config, this.log);
const options = {
cameraStreamCount: 2,
delegate: streamingDelegate,
streamingOptions: {
supportedCryptoSuites: [0],
video: {
resolutions: [
[320, 180, 30],
[320, 240, 15],
[320, 240, 30],
[480, 270, 30],
[480, 360, 30],
[640, 360, 30],
[640, 480, 30],
[1280, 720, 30],
[1280, 960, 30],
[1920, 1080, 30],
[1600, 1200, 30],
],
codec: {
profiles: [0, 1, 2],
levels: [0, 1, 2],
},
},
audio: {
twoWayAudio: this.camera.info.capabilities.includes('audio.microphone'),
codecs: [
{
type: "AAC-eld",
samplerate: 16,
},
],
},
},
};
const cameraController = new this.hap.CameraController(options);
streamingDelegate.controller = cameraController;
this.accessory.configureController(cameraController);
}
getServicesByType(serviceType) {
return this.accessory.services.filter((x) => x.UUID === serviceType.UUID);
}
async toggleActive(enabled) {
const service = this.accessory.getService(`${this.accessory.displayName} Streaming`);
const set = await this.camera.setBooleanProperty('streaming.enabled', enabled);
if (set && service) {
service.updateCharacteristic(this.hap.Characteristic.On, enabled);
}
}
async toggleChime(enabled) {
const service = this.accessory.getService(`${this.accessory.displayName} Chime`);
const set = await this.camera.setBooleanProperty('doorbell.indoor_chime.enabled', enabled);
if (set && service) {
service.updateCharacteristic(this.hap.Characteristic.On, enabled);
}
}
async toggleAnnouncements(enabled) {
const service = this.accessory.getService(`${this.accessory.displayName} Announcements`);
const set = await this.camera.setBooleanProperty('doorbell.chime_assist.enabled', enabled);
if (set && service) {
service.updateCharacteristic(this.hap.Characteristic.On, enabled);
}
}
async toggleAudio(enabled) {
const service = this.accessory.getService(`${this.accessory.displayName} Audio`);
const set = await this.camera.setBooleanProperty('audio.enabled', enabled);
if (set && service) {
service.updateCharacteristic(this.hap.Characteristic.On, enabled);
}
}
setMotion(state, types) {
if (this.hap) {
types.forEach((type) => {
type = sanitizeString(type);
const service = this.accessory.getServiceById(this.hap.Service.MotionSensor, `${this.accessory.displayName} ${type}`);
if (service) {
this.log.debug(`Setting ${this.accessory.displayName} ${type} Motion to ${state}`);
service.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
}
});
}
}
setDoorbell() {
const doorbellService = this.accessory.getServiceById(this.hap.Service.Doorbell, `${this.accessory.displayName} Doorbell`);
if (doorbellService) {
this.log.debug(`Ringing ${this.accessory.displayName} Doorbell`);
doorbellService.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent, this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
}
const switchService = this.accessory.getService(this.hap.Service.StatelessProgrammableSwitch);
if (switchService) {
switchService.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent, this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
}
}
}
exports.NestAccessory = NestAccessory;
//# sourceMappingURL=accessory.js.map