alb3rt-home-security
Version:
183 lines (155 loc) • 5.42 kB
JavaScript
'use strict';
const FILE_ID = '[alb3rt-home-security/state]',
core = require('alb3rt-core'),
http = core.http,
sensors = require('alb3rt-sensors'),
tts = require('alb3rt-tts'),
moment = require('moment'),
CONFIG = core.config,
email = core.email,
incidents = require('../incidents');
module.exports = new class HomeSecurityState {
constructor() {
this.$enabled = false;
this.$armed = false;
this.armedTimeout = null;
this.enable = this.enable.bind(this);
this.disable = this.disable.bind(this);
}
get armed() {
return this.$armed;
}
get enabled() {
return this.$enabled;
}
notifyMaster(device) {
http.post({
url: CONFIG.MASTER_SERVER_ADDRESS + '/api/security',
body: {
type: 'motion',
device
}
}, (err, res) => {
if (err || res.statusCode !== 200) {
console.warn(FILE_ID, 'Notifying master about motion unsuccessful. Error: ' + (err || res.statusCode));
}
});
}
arm() {
if (!this.armedTimeout) {
const self = this;
this.armedTimeout = setTimeout(() => {
self.$armed = true;
console.log(FILE_ID, 'Alarm armed.');
clearTimeout(self.armedTimeout);
delete self.armedTimeout;
}, 3000);
}
}
enable(statusText, passcode) {
this.$enabled = true;
this.arm();
tts.say('SECURITY_ENABLED');
console.info(FILE_ID + ' ' + statusText);
sensors.motion.on();
sensors.motion.subscribe('home-security-motion', 'motion', device => {
console.log(FILE_ID, 'Motion detected. Activating camera at', device.name);
sensors.camera.on();
if (CONFIG.ROLE !== 'master') {
this.notifyMaster(device);
}
});
if (CONFIG.ROLE === 'master') {
core.instance.extend({
security: {
enabled: true
}
});
core.broadcast.trigger('security', {
type: 'state',
state: true,
passcode
});
core.registry.subscribe('SECURITY', 'unregister', (device) => {
console.log('OOO, wyrejestrowal sie!', device);
// CONFIG.SECURITY_EMAILS_TO.forEach(address => {
// if (address) {
// const subjectPrefix = this.slaves.length ? '[Alb3rt Warning]' : '[Alb3rt Alert]',
// subjectMain = this.slaves.length ? `Slave device ${device.name} disconnected` : 'No registered slaves',
// subject = `${subjectPrefix} ${subjectMain}`,
// text = `The ${device.name} at ${device.ip}:${device.port} has been disconnected at ${moment().format()}.`;
// email.send({
// address,
// subject,
// text
// });
// }
// });
});
}
}
disable(statusText, passcode) {
this.$enabled = false;
if (this.armedTimeout) {
clearTimeout(this.armedTimeout);
delete this.armedTimeout;
}
this.$armed = false;
tts.say('SECURITY_DISABLED');
console.info(FILE_ID + ' ' + statusText);
sensors.motion.off();
sensors.motion.unsubscribe('home-security-motion', 'motion');
if (CONFIG.ROLE === 'master') {
core.instance.extend({
security: {
enabled: false
}
});
core.broadcast.trigger('security', {
type: 'state',
state: false,
passcode
});
core.registry.unsubscribe('SECURITY', 'unregister');
}
incidents.sendSummary();
}
handle(data, response) {
let statusCode = 200,
statusText;
if (CONFIG.SECURITY_PASSCODES.indexOf(data.passcode) !== -1) {
switch (data.state) {
case true:
case 'true':
if (this.$enabled === false) {
statusText = 'Security enabled.';
this.enable(statusText, data.passcode);
} else {
statusText = 'Security already enabled. Aborting...';
}
break;
case false:
case 'false':
if (this.$enabled === true) {
statusText = 'Security disabled.';
this.disable(statusText, data.passcode);
} else {
statusText = 'Security already disabled. Aborting...';
}
break;
default:
break;
}
} else {
statusText = 'Incorrect password provided. Aborting...';
console.log(FILE_ID, statusText);
statusCode = 401;
}
core.api.responder.send(response, {
status: statusCode,
data: {
status: statusText
}
});
}
};