You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.4 KiB
JavaScript
170 lines
4.4 KiB
JavaScript
require("dotenv").config();
|
|
const mqtt = require("mqtt");
|
|
const express = require("express");
|
|
|
|
const db = require("./db");
|
|
|
|
const { Armed, Disarmed, Triggered, Arming, Disarming } = require("./state");
|
|
|
|
const app = express();
|
|
|
|
app.use(require("./routes"))
|
|
|
|
app.use(express.static("public"));
|
|
|
|
app.listen(process.env.PORT || 8080, () => {
|
|
console.log(`Listening on port ${process.env.PORT || 8080}`);
|
|
});
|
|
|
|
const mqttClient = mqtt.connect(process.env.MQTT, { clean: true, });
|
|
|
|
mqttClient.on("connect", (a) => {
|
|
console.log(`Connected to ${process.env.MQTT}`);
|
|
// mqttClient.publish("door/lock", JSON.stringify({ deviceId: 2, lock: true }));
|
|
// setTimeout(() => {
|
|
// mqttClient.publish("door/lock", JSON.stringify({ deviceId: 2, lock: false }));
|
|
// }, 3000);
|
|
|
|
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: alarmStatus }));
|
|
// mqttClient.publish("alarm/state", JSON.stringify({ status: "Triggered" }));
|
|
// setTimeout(() => {
|
|
// mqttClient.publish("alarm/state", JSON.stringify({ status: "Arming" }));
|
|
// }, 5000);
|
|
});
|
|
|
|
mqttClient.subscribe("motion");
|
|
// mqttClient.subscribe("sound");
|
|
mqttClient.subscribe("temperature");
|
|
mqttClient.subscribe("light");
|
|
mqttClient.subscribe("door/status");
|
|
mqttClient.subscribe("display/arm");
|
|
mqttClient.subscribe("display/disarm");
|
|
|
|
function insertEvent(deviceId, eventType) {
|
|
db.query(`
|
|
INSERT INTO events (deviceId, type)
|
|
VALUES ($1, $2)
|
|
`, [
|
|
deviceId,
|
|
eventType
|
|
]);
|
|
}
|
|
|
|
function triggerAlarm(deviceId) {
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: Triggered }));
|
|
alarmStatus = Triggered;
|
|
console.log("Alarm has been triggered");
|
|
insertEvent(deviceId, Triggered);
|
|
}
|
|
|
|
function disarmingAlarm(deviceId) {
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: Disarming }));
|
|
alarmStatus = Disarming;
|
|
console.log("Alarm has been set to Disarming");
|
|
timer = setTimeout(disarmingTimerRunout, 30, deviceId);
|
|
insertEvent(deviceId, Disarming);
|
|
}
|
|
|
|
function disarmingTimerRunout(deviceId) {
|
|
if (alarmStatus === Disarming) {
|
|
triggerAlarm(deviceId);
|
|
}
|
|
}
|
|
|
|
function armAlarm(deviceId) {
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: Arming }));
|
|
alarmStatus = Arming;
|
|
console.log("Alarm has been set to Arming");
|
|
timer = setTimeout(armingTimerRunout, 30, deviceId);
|
|
insertEvent(deviceId, Arming);
|
|
}
|
|
|
|
function armingTimerRunout(deviceId) {
|
|
if (alarmStatus === Arming) {
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: Armed }));
|
|
mqttClient.publish("door/lock", JSON.stringify({ deviceId: 2, lock: true }));
|
|
alarmStatus = Armed;
|
|
console.log("Alarm has been set to Armed");
|
|
insertEvent(deviceId, Armed);
|
|
}
|
|
}
|
|
|
|
function disarmAlarm(deviceId) {
|
|
mqttClient.publish("alarm/state", JSON.stringify({ status: Disarmed }));
|
|
mqttClient.publish("door/lock", JSON.stringify({ deviceId: 2, lock: false }));
|
|
alarmStatus = Disarmed;
|
|
clearTimeout(timer);
|
|
console.log("Alarm has been set to Disarmed");
|
|
insertEvent(deviceId, Disarmed);
|
|
}
|
|
|
|
let timer;
|
|
|
|
let alarmStatus = Armed;
|
|
|
|
mqttClient.on("message", (topic, message) => {
|
|
// console.log(topic, message.toString());
|
|
switch (topic) {
|
|
case "motion": {
|
|
const data = JSON.parse(message);
|
|
if ((alarmStatus === Armed || alarmStatus === Triggered) && data.value === true) {
|
|
console.log("motion");
|
|
triggerAlarm(data.deviceId);
|
|
}
|
|
break;
|
|
}
|
|
case "sound": {
|
|
const data = JSON.parse(message);
|
|
if (alarmStatus === Armed || alarmStatus === Triggered) {
|
|
console.log("sound", data.value);
|
|
triggerAlarm(data.deviceId);
|
|
}
|
|
break;
|
|
}
|
|
case "door/status": {
|
|
const data = JSON.parse(message);
|
|
console.log(data);
|
|
if ((alarmStatus === Armed || alarmStatus === Triggered) && data.open === true) {
|
|
console.log("door sensor");
|
|
disarmingAlarm(data.deviceId);
|
|
}
|
|
break;
|
|
}
|
|
case "arm": {
|
|
const data = JSON.parse(message);
|
|
armAlarm(data.deviceId);
|
|
break;
|
|
}
|
|
case "disarm": {
|
|
const data = JSON.parse(message);
|
|
disarmAlarm(data.deviceId);
|
|
break;
|
|
}
|
|
case "light": {
|
|
const data = JSON.parse(message);
|
|
db.query(`
|
|
INSERT INTO light_measurements (deviceId, value)
|
|
VALUES ($1, $2)
|
|
`, [
|
|
data.deviceId,
|
|
data.value
|
|
]);
|
|
break;
|
|
}
|
|
case "temperature": {
|
|
const data = JSON.parse(message);
|
|
db.query(`
|
|
INSERT INTO temperature_measurements (deviceId, value)
|
|
VALUES ($1, $2)
|
|
`, [
|
|
data.deviceId,
|
|
data.value
|
|
]);
|
|
break;
|
|
}
|
|
default:
|
|
console.log("Unsupported topic received: " + topic);
|
|
break;
|
|
}
|
|
}); |