@koush/ring-client-api
Version:
Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting
146 lines (145 loc) • 6.74 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecurityPanel = void 0;
const base_device_accessory_1 = require("./base-device-accessory");
const api_1 = require("../api");
const hap_1 = require("./hap");
function isValidNightModeBypass(mode) {
return mode && (mode === 'all' || mode === 'some');
}
class SecurityPanel extends base_device_accessory_1.BaseDeviceAccessory {
constructor(device, accessory, logger, config) {
super();
this.device = device;
this.accessory = accessory;
this.logger = logger;
this.config = config;
this.alarmStates = this.config.alarmOnEntryDelay
? api_1.allAlarmStates
: api_1.allAlarmStates.filter((x) => x !== 'entry-delay');
this.targetingNightMode = false;
const { Characteristic, Service } = hap_1.hap, validValues = [
Characteristic.SecuritySystemTargetState.AWAY_ARM,
Characteristic.SecuritySystemTargetState.STAY_ARM,
Characteristic.SecuritySystemTargetState.DISARM,
];
if (isValidNightModeBypass(config.nightModeBypassFor)) {
validValues.push(Characteristic.SecuritySystemTargetState.NIGHT_ARM);
}
this.registerCharacteristic({
characteristicType: Characteristic.SecuritySystemCurrentState,
serviceType: Service.SecuritySystem,
getValue: (data) => this.getCurrentState(data),
});
this.registerCharacteristic({
characteristicType: Characteristic.SecuritySystemTargetState,
serviceType: Service.SecuritySystem,
getValue: (data) => this.getTargetState(data),
setValue: (value) => this.setTargetState(value),
});
this.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.setProps({ validValues });
if (!config.hideAlarmSirenSwitch) {
this.registerCharacteristic({
characteristicType: Characteristic.On,
serviceType: Service.Switch,
name: this.device.name + ' Siren',
getValue: (data) => data.siren && data.siren.state === 'on',
setValue: (value) => {
if (value) {
return this.device.location.soundSiren();
}
return this.device.location.silenceSiren();
},
});
}
this.getService(Service.SecuritySystem).setPrimaryService(true);
}
getTargetNightMode() {
return this.targetingNightMode && this.config.nightModeBypassFor;
}
getTargetState({ mode }) {
const { Characteristic: { SecuritySystemTargetState: State }, } = hap_1.hap;
if (mode === this.getTargetNightMode()) {
setTimeout(() => {
// clear in next tick so that Target and Current state both get night mode
this.targetingNightMode = false;
});
return State.NIGHT_ARM;
}
switch (mode) {
case 'all':
return State.AWAY_ARM;
case 'some':
return State.STAY_ARM;
case 'none':
return State.DISARM;
default:
return State.DISARM;
}
}
getCurrentState(data) {
const { alarmInfo } = data;
if (alarmInfo && this.alarmStates.includes(alarmInfo.state)) {
return hap_1.hap.Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED;
}
return this.getTargetState(data);
}
setTargetState(state) {
return __awaiter(this, void 0, void 0, function* () {
const { Characteristic: { SecuritySystemTargetState: State }, } = hap_1.hap, { location } = this.device, { nightModeBypassFor } = this.config;
let bypass = false;
this.targetingNightMode = state === State.NIGHT_ARM;
if (state === State.NIGHT_ARM) {
if (nightModeBypassFor &&
(nightModeBypassFor === 'all' || nightModeBypassFor === 'some')) {
state = nightModeBypassFor === 'all' ? State.AWAY_ARM : State.STAY_ARM;
bypass = true;
}
else {
// Switch to Home since we don't know which mode the user wanted
state = State.STAY_ARM;
}
}
const bypassContactSensors = bypass
? (yield location.getDevices()).filter((device) => {
return (device.deviceType === api_1.RingDeviceType.ContactSensor &&
device.data.faulted);
})
: [], bypassSensorZids = bypassContactSensors.map((sensor) => sensor.id), bypassSensorNames = bypassContactSensors.map((sensor) => sensor.name), bypassLog = bypassSensorNames.length
? ' - Bypassing Sensors: ' + bypassSensorNames.join(', ')
: '';
try {
if (state === State.AWAY_ARM) {
this.logger.info(`Arming (Away) ${this.device.name}${bypassLog}`);
yield location.armAway(bypassSensorZids);
}
else if (state === State.DISARM) {
this.logger.info(`Disarming ${this.device.name}`);
yield location.disarm();
}
else {
this.logger.info(`Arming (Home) ${this.device.name}${bypassLog}`);
yield location.armHome(bypassSensorZids);
}
}
catch (e) {
this.logger.error(e);
this.getService(hap_1.hap.Service.SecuritySystem)
.getCharacteristic(hap_1.hap.Characteristic.SecuritySystemTargetState)
.updateValue(this.getTargetState(this.device.data));
}
});
}
}
exports.SecurityPanel = SecurityPanel;