├── lib ├── key.pem ├── cert.pem ├── mqttclient │ ├── ca.cert │ ├── client.cert │ └── client.key ├── config.json ├── server.js └── page.html.template ├── AUTHORS ├── pictures ├── alarm_main_window.jpg ├── alarm_main_window_armed.jpg ├── alarm_main_window_phone.jpg ├── alarm_camera_picture_view.jpg ├── alarm_main_window_native.jpg └── alarm_main_window_triggered.jpg ├── package.json ├── LICENSE.txt └── README.md /lib/key.pem: -------------------------------------------------------------------------------- 1 | add your key here 2 | -------------------------------------------------------------------------------- /lib/cert.pem: -------------------------------------------------------------------------------- 1 | Add your cert here 2 | -------------------------------------------------------------------------------- /lib/mqttclient/ca.cert: -------------------------------------------------------------------------------- 1 | add your cert here 2 | 3 | -------------------------------------------------------------------------------- /lib/mqttclient/client.cert: -------------------------------------------------------------------------------- 1 | add your client cert here 2 | 3 | -------------------------------------------------------------------------------- /lib/mqttclient/client.key: -------------------------------------------------------------------------------- 1 | Add your client key here 2 | 3 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Below is a list of people that have contributed to the 2 | # project 3 | 4 | Michael Dawson 5 | -------------------------------------------------------------------------------- /pictures/alarm_main_window.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_main_window.jpg -------------------------------------------------------------------------------- /pictures/alarm_main_window_armed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_main_window_armed.jpg -------------------------------------------------------------------------------- /pictures/alarm_main_window_phone.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_main_window_phone.jpg -------------------------------------------------------------------------------- /pictures/alarm_camera_picture_view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_camera_picture_view.jpg -------------------------------------------------------------------------------- /pictures/alarm_main_window_native.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_main_window_native.jpg -------------------------------------------------------------------------------- /pictures/alarm_main_window_triggered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/HEAD/pictures/alarm_main_window_triggered.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "micro-app-home-alarm", 3 | "version": "2.0.0", 4 | "description": "Alarm dashboard written in node", 5 | "main": "lib/server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node lib/server.js" 9 | }, 10 | "dependencies": { 11 | "micro-app-framework": "^0.1.1", 12 | "micro-app-notify-client": "^0.0.1", 13 | "socket.io": "~1.3.7", 14 | "mqtt": "~1.6.3" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/mhdawson/micro-app-home-alarm.git" 19 | }, 20 | "keywords": [ 21 | "iot", 22 | "mqtt", 23 | "dashboard", 24 | "micro-app", 25 | "sensor", 26 | "alarm", 27 | "sms", 28 | "webcam" 29 | ], 30 | "author": "Michael Dawson", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/mhdawson/micro-app-home-alarm/issues" 34 | }, 35 | "homepage": "https://github.com/mhdawson/micro-app-home-alarm#readme", 36 | "contributors": [ 37 | { 38 | "name": "Michael Dawson", 39 | "email": "mdawson@devrus.com" 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2016 the project authors as listed in the AUTHORS file 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /lib/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Cottage Alarm", 3 | "alarmSite": "Home", 4 | "serverPort": 3000, 5 | "tls": "true", 6 | "authenticate": "true", 7 | "scrollBars": true, 8 | "authInfo": {"username": "alarm", "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "realm": "alarm"}, 9 | "mqtt": { "serverUrl": "mqtts:XXXXXXXXX:8883", 10 | "rootTopic": "house", 11 | "certsDir": "./certs" }, 12 | "webserverUrlForPictures": "https:XXXXXXXXXX:XXXXX", 13 | "zones": [ { "topic": "house/2262/1", "zoneId": 3, "label": "front door" }, 14 | { "topic": "house/2262/2", "zoneId": 4, "label": "patio door" }, 15 | { "topic": "house/2262/3", "zoneId": 2, "label": "motion living" }, 16 | { "topic": "house/2262/4", "zoneId": 1, "label": "motion hall" }, 17 | { "topic": "house/2262/5", "zoneId": 5, "label": "fire" } 18 | ], 19 | "camera": { "topic": "house/camera", 20 | "IRtopic": "home/2272", 21 | "IRon": "FFFFFFF11000", 22 | "IRoff": "FFFFFFF10000" }, 23 | "eventLogPrefix": "/home/user1/repos/micro-app-home-alarm", 24 | "notify": { 25 | "mqttSmsBridge": { "enabled": true, 26 | "serverUrl": "your mqtt server", 27 | "topic": "house/sms" } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MQTT/Node base home alarm system 2 | 3 | This is a port of the [HomeAlarm](https://github.com/mhdawson/HomeAlarm) project 4 | over to the micro-app framwork so that you can get the native 5 | look and feel on desktop and mobile devices with the 6 | [micro-app-cordova-launcher](https://github.com/mhdawson/micro-app-cordova-launcher) 7 | and [micro-app-electron-launcher](https://github.com/mhdawson/micro-app-electron-launcher) 8 | projects. 9 | 10 | This projects provides a home based alarm system using Node and 11 | MQTT. It provides a GUI that allows you to: 12 | 13 | * arm/disarm the alarm 14 | * see the status of the zones 15 | * ask that a picture be taken 16 | * view the last 4 pictures taken 17 | * view pictures from multiple cameras 18 | * view the log of alarm events 19 | 20 | When the alarm is triggered it will take pictures every 10 second for 5 minutes, pushing them to a remote webserver. 21 | It can also be configured to send sms messages to notify the owner than an alarm has occured. 22 | 23 | In a browser: 24 | 25 | ![picture of alarm main window](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_main_window.jpg?raw=true) 26 | 27 | Native application: 28 | 29 | ![picture of alarm main window](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_main_window_native.jpg?raw=true) 30 | 31 | On a phone: 32 | 33 | ![picture of alarm main window on phone](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_main_window_phone.jpg?raw=true) 34 | 35 | The following projects can be used to connect sensors such 36 | motion detectors, door contacts and webcams. 37 | * [PI433WirelessRecvMananager](https://github.com/mhdawson/PI433WirelessRecvManager) 38 | or this less expensive project 39 | [Mqtt433Bridge](https://github.com/mhdawson/arduino-esp8266/tree/master/Mqtt433Bridge). 40 | 41 | * [PIWebcamServer](https://github.com/mhdawson/PIWebcamServer) 42 | 43 | Additional views when alarm is active and triggered 44 | 45 | ![picture of alarm when armed](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_main_window_armed.jpg?raw=true) 46 | ![picture of alarm when triggered](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_main_window_triggered.jpg?raw=true) 47 | 48 | View when using GUI to display pictures taken by camera 49 | 50 | ![sample camera picture view](https://raw.githubusercontent.com/mhdawson/micro-app-home-alarm/master/pictures/alarm_camera_picture_view.jpg?raw=true) 51 | 52 | The server requires Node along with the modules defined in the package.json 53 | file to be installed. 54 | 55 | It also requires: 56 | 57 | * an mqtt server 58 | * a remote webserver to serve up the pictures taken 59 | * twillio account (If you want SMS notifications) 60 | 61 | # Configuration 62 | 63 | Most configuration is done in the config.json file which supports the 64 | following configuration options: 65 | 66 | * title - title used to name the page for the app 67 | * alarmSite - Name assigned to this instance of the alarm 68 | * serverPort - port on which micro-app is listening for connections 69 | * tls - set to the string "true" if you want to force tls when connecting 70 | * authenticate - set to "true" to enable basic authentication. If set 71 | to true then you must provide the "authInfo" values described below 72 | * scrollBars - set this to "true" so that you can scroll when viweing the log 73 | file 74 | * authInfo - object with username, password and realm values. authInfo.password is 75 | the hashed password that will be used to authenticate to the micro-app. 76 | This can be generated with the utility in the micro-app framework which 77 | is called: .../node_modules/micro-app-framework/lib/gen_password.js. 78 | The first parameter is the password to be hashed. 79 | * mqtt - object with serverUrl, rootTopic and certsDir. If the serverUrl 80 | uses tls (ex mqtts: then certsDir must contain the required certificates 81 | etc. needed to connect to the mqtt server using tls) 82 | * zone - array objects, each of which specifies the topic, zoneId and label 83 | for one of the alarm zones 84 | * camera - object with topic used to communicate with the camera server 85 | and topics and messages used to communicate with an IR illuminator (see 86 | https://github.com/mhdawson/PI433WirelessTXManager for the circuit 87 | used to turn on/off the power supply for the IR illuminator) 88 | * eventLogPrefix - directory in which log for alarm will be written 89 | * notify - configuration for notification options 90 | * mqttSmsBridge - element with the following sub-elements: 91 | * enabled - set to true if you want notifications to 92 | be sent using this provider. 93 | * serverUrl - url for the mqtt server to which the 94 | bridge is connected. 95 | * topic - topic on which the bridge listens for 96 | notification requests. 97 | * certs - directory which contains the keys/certs 98 | required to connect to the mqtt server if the 99 | url is of type `mqtts`. 100 | * voipms - element with the following sub-elements: 101 | * enabled - set to true if you want notifications to 102 | be sent using this provider. 103 | * user - voip.ms API userid. 104 | * password - voip.ms API password. 105 | * did - voip.ms did(number) from which the SMS will be sent. 106 | * dst - number to which the SMS will be sent. 107 | * twilio - element with the following sub-elements: 108 | * enabled - set to true if you want notifications to 109 | be sent using this provider. 110 | 111 | 112 | For example this is my configuration file with some key elements 113 | masked out: 114 | 115 |
116 | {
117 |   "title": "Cottage Alarm",
118 |   "alarmSite": "Home",
119 |   "serverPort": 3000,
120 |   "tls": "true",
121 |   "authenticate": "true",
122 |   "scrollBars": true,
123 |   "authInfo": {"username": "alarm", "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "realm": "alarm"},
124 |   "mqtt": { "serverUrl": "mqtts:XXXXXXXXX:8883",
125 |             "rootTopic": "house",
126 |             "certsDir": "./certs" },
127 |   "webserverUrlForPictures": "https:XXXXXXXXXX:XXXXX",
128 |   "zones": [ { "topic": "house/2262/1", "zoneId": 3, "label": "front door" },
129 |              { "topic": "house/2262/2", "zoneId": 4, "label": "patio door" },
130 |              { "topic": "house/2262/3", "zoneId": 2, "label": "motion living" },
131 |              { "topic": "house/2262/4", "zoneId": 1, "label": "motion hall" },
132 |              { "topic": "house/2262/5", "zoneId": 5, "label": "fire" }
133 |            ],
134 |   "camera": { "topic": "house/camera",
135 |               "IRtopic": "home/2272",
136 |               "IRon": "FFFFFFF11000",
137 |               "IRoff": "FFFFFFF10000" },
138 |   "eventLogPrefix": "/home/user1/repos/micro-app-home-alarm",
139 |   "notify": {
140 |     "mqttSmsBridge": { "enabled": true,
141 |                        "serverUrl": "your mqtt server",
142 |                        "topic": "house/sms" }
143 |   }
144 | }
145 | 
146 | 147 | # Installation 148 | 149 | The easiest way to install is to run: 150 | 151 |
152 | npm install micro-app-home-alarm
153 | 
154 | 155 | and then configure the default config.json file in the lib directory as described 156 | in the configuration section above. 157 | 158 | # Running 159 | 160 | Simply cd to the directory where the npm was installed and type: 161 | 162 |
163 | npm start
164 | 
165 | 166 | # Key Depdencies 167 | 168 | ## micro-app-framework 169 | As a micro-app the micro-app-alert-dashboard app depends on the micro-app-framework: 170 | 171 | * [micro-app-framework npm](https://www.npmjs.com/package/micro-app-framework) 172 | * [micro-app-framework github](https://github.com/mhdawson/micro-app-framework) 173 | 174 | See the documentation on the micro-app-framework for more information on general 175 | configurtion options that are availble (ex using tls, authentication, serverPort, etc) 176 | 177 | ## micro-app-notify-client 178 | 179 | * [micro-app-notify-client](https://github.com/mhdawson/micro-app-notify-client) 180 | 181 | The micro-app-notify-client is used to send notifications through sms and other 182 | means when necessary. 183 | 184 | ## TODOs 185 | - Add more doc on how to configure, setup and run, including the required mqtt server 186 | -------------------------------------------------------------------------------- /lib/server.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2017 the project authors as listed in the AUTHORS file. 2 | // All rights reserved. Use of this source code is governed by the 3 | // license that can be found in the LICENSE file. 4 | const fs = require('fs'); 5 | const mqtt = require('mqtt'); 6 | const notify = require('micro-app-notify-client'); 7 | const path = require('path'); 8 | const socketio = require('socket.io'); 9 | 10 | // constants 11 | const PAGE_HEIGHT = 320; 12 | const PAGE_WIDTH = 390; 13 | const NUM_ZONES = 8; 14 | const ZONE_STATUS = '/status'; 15 | const ZONE_NAME = '/name'; 16 | const CAMERA_CAPTURE = '/capture'; 17 | const CAMERA_NEWPICTURE = '/newpicture'; 18 | 19 | // this is filled in later as the socket io connection is established 20 | var eventSocket; 21 | 22 | // alarm state and data 23 | var latestData = {}; 24 | var zoneMapping = {}; 25 | 26 | /////////////////////////////////////////////// 27 | // Camera handling functions 28 | /////////////////////////////////////////////// 29 | // camera configuration 30 | var cameraCaptureTopic; 31 | var pictureTimer = undefined; 32 | var picture1 = ''; 33 | var picture2 = ''; 34 | var picture3 = ''; 35 | var picture4 = ''; 36 | 37 | function stopPictureTimer() { 38 | if (pictureTimer !== undefined) { 39 | clearInterval(pictureTimer); 40 | pictureTimer = undefined; 41 | } 42 | } 43 | 44 | // function to request that a picture be taken 45 | var irTimer = undefined; 46 | var cameraCaptureTopic; 47 | function takePicture(mqttClient) { 48 | irOn(mqttClient); 49 | irOn(mqttClient); 50 | irOn(mqttClient); 51 | 52 | // leave some time for the ir light to illuminate 53 | setTimeout(function() { 54 | mqttClient.publish(cameraCaptureTopic, 'take'); 55 | }, 10); 56 | 57 | // now give the pi 60 seconds to take the picture 58 | // and then turn off the ir light. If another 59 | // picture request comes before the first one 60 | // is complete the timer is reset so we should 61 | // always get 60s after the request for the last 62 | // picture 63 | if (irTimer != undefined) { 64 | clearInterval(irTimer); 65 | } 66 | irTimer = setInterval(function() { 67 | irOff(mqttClient); 68 | irOff(mqttClient); 69 | irOff(mqttClient); 70 | clearInterval(irTimer); 71 | irTimer = undefined; 72 | }, 30000); 73 | } 74 | 75 | 76 | function irOn(mqttClient) { 77 | if ((undefined != Server.config.camera.IRtopic) && (undefined != Server.config.camera.IRon)) { 78 | mqttClient.publish(Server.config.camera.IRtopic, Server.config.camera.IRon); 79 | } 80 | } 81 | 82 | 83 | function irOff(mqttClient) { 84 | if ((undefined != Server.config.camera.IRtopic) && (undefined != Server.config.camera.IRoff)) { 85 | mqttClient.publish(Server.config.camera.IRtopic, Server.config.camera.IRoff); 86 | } 87 | } 88 | 89 | 90 | /////////////////////////////////////////////// 91 | // Logging 92 | /////////////////////////////////////////////// 93 | var eventLogFile; 94 | function logEvent(event) { 95 | // no point to provide error function as we won't do 96 | // anything in case of an error 97 | fs.appendFile(eventLogFile, new Date() + ' :' + event + '\n'); 98 | } 99 | 100 | 101 | /////////////////////////////////////////////// 102 | // micro-app framework methods 103 | /////////////////////////////////////////////// 104 | var Server = function() { 105 | } 106 | 107 | 108 | Server.getDefaults = function() { 109 | return { 'title': 'Alarm Console' }; 110 | } 111 | 112 | 113 | var replacements; 114 | Server.getTemplateReplacments = function() { 115 | if (replacements === undefined) { 116 | var config = Server.config; 117 | replacements = [{ 'key': '', 'value': config.title }, 118 | { 'key': '', 'value': config.title }, 119 | { 'key': '', 'value': config.webserverUrlForPictures }, 120 | { 'key': '', 'value': config.webserverUrlForPictures }, 121 | { 'key': '', 'value': config.webserverUrlForPictures }, 122 | { 'key': '', 'value': PAGE_WIDTH }, 123 | { 'key': '', 'value': PAGE_HEIGHT }]; 124 | 125 | } 126 | return replacements; 127 | } 128 | 129 | 130 | Server.handleSupportingPages = function(request, response) { 131 | // ok now server the appropriate page base on the request type 132 | if (request.url.indexOf("getlog") > -1) { 133 | var logFile = fs.readFileSync(eventLogFile); 134 | response.writeHead(200, {'Content-Type': 'text/html'}); 135 | response.end(logFile); 136 | return true; 137 | } 138 | return false; 139 | }; 140 | 141 | 142 | Server.startServer = function(server) { 143 | var config = Server.config; 144 | var newPictureTopic = config.camera.topic + CAMERA_NEWPICTURE; 145 | cameraCaptureTopic = config.camera.topic + CAMERA_CAPTURE; 146 | var alarmStatusTopic = config.mqtt.rootTopic + '/alarm/status'; 147 | var zoneTopicPrefix = config.mqtt.rootTopic + '/alarm/zone/'; 148 | eventLogFile = path.join(Server.config.eventLogPrefix, 'alarm_event_log'); 149 | 150 | for (var i = 0; i < config.zones.length; i++) { 151 | zoneMapping[config.zones[i].topic] = zoneTopicPrefix + config.zones[i].zoneId + ZONE_STATUS; 152 | latestData[zoneTopicPrefix + config.zones[i].zoneId + ZONE_NAME] = config.zones[i].label; 153 | } 154 | 155 | eventSocket = socketio.listen(server); 156 | 157 | // setup mqtt 158 | var mqttOptions; 159 | if (config.mqtt.serverUrl.indexOf('mqtts') > -1) { 160 | mqttOptions = { key: fs.readFileSync(path.join(__dirname, 'mqttclient', '/client.key')), 161 | cert: fs.readFileSync(path.join(__dirname, 'mqttclient', '/client.cert')), 162 | ca: fs.readFileSync(path.join(__dirname, 'mqttclient', '/ca.cert')), 163 | checkServerIdentity: function() { return undefined } 164 | } 165 | } 166 | 167 | var mqttClient = mqtt.connect(config.mqtt.serverUrl, mqttOptions); 168 | 169 | /* each time we connect register on all topics we are interested 170 | * in. This must be done after a reconnect as well as the 171 | * initial connect 172 | */ 173 | mqttClient.on('connect',function() { 174 | mqttClient.subscribe(alarmStatusTopic); 175 | mqttClient.subscribe(zoneTopicPrefix + '+/+'); 176 | mqttClient.subscribe(newPictureTopic); 177 | for(topic in zoneMapping) { 178 | mqttClient.subscribe(topic); 179 | } 180 | }); 181 | 182 | mqttClient.on('message', function(topic, message) { 183 | latestData[topic] = message; 184 | if (alarmStatusTopic == topic) { 185 | if (('arm' == message) || ('disarm' == message)) { 186 | // first clear the state of all of the zones 187 | for(i=1;i < NUM_ZONES+1; i++) { 188 | mqttClient.publish(zoneTopicPrefix + i + ZONE_STATUS, 'off'); 189 | } 190 | // stop taking pictures if we are as we are reseting the alarm state 191 | stopPictureTimer(); 192 | 193 | if ('arm' == message) { 194 | logEvent('Armed'); 195 | } else { 196 | logEvent('Dis-Armed'); 197 | } 198 | } else if ('triggered' == message) { 199 | logEvent('Alarm Triggered:' + Date()); 200 | 201 | // take pictures every 10 seconds for 5 minutes after the alarm is triggered 202 | var count = 0; 203 | stopPictureTimer(); 204 | pictureTimer = setInterval(function() { 205 | takePicture(mqttClient); 206 | count++; 207 | if (30 < count) { 208 | stopPictureTimer(); 209 | } 210 | }, 10000); 211 | 212 | // send sms message indicating alarm has been triggered 213 | notify.sendNotification(config, 'Alarm triggered:' + config.alarmSite); 214 | logEvent('SMS Sent:' + message.sid); 215 | } 216 | } else if (topic == newPictureTopic) { 217 | // seems like we sometimes get duplicates, avoid adding these to the picture rotation 218 | if ((message != picture1) && 219 | (message != picture2) && 220 | (message != picture3) && 221 | (message != picture4)) { 222 | picture4 = picture3 223 | picture3 = picture2 224 | picture2 = picture1 225 | picture1 = message; 226 | } 227 | } 228 | 229 | if (undefined != zoneMapping[topic]) { 230 | // sensor alarm, map and publish alarm event 231 | mqttClient.publish(zoneMapping[topic], 'on'); 232 | logEvent('Zone triggered - ' + zoneMapping[topic]); 233 | 234 | // if we are armed then system has been triggered 235 | if ('arm' == latestData[alarmStatusTopic]) { 236 | mqttClient.publish(alarmStatusTopic, 'triggered'); 237 | } 238 | } else { 239 | // other message publish directly to clients 240 | eventSocket.emit('message', topic + ":" + message); 241 | } 242 | }); 243 | 244 | eventSocket.on('connection', function(ioclient) { 245 | for (key in latestData) { 246 | if (key != newPictureTopic) { 247 | eventSocket.to(ioclient.id).emit('message', key + ":" + latestData[key]); 248 | } 249 | } 250 | 251 | // send the latest pictures 252 | eventSocket.to(ioclient.id).emit('message', newPictureTopic + ":" + picture4); 253 | eventSocket.to(ioclient.id).emit('message', newPictureTopic + ":" + picture3); 254 | eventSocket.to(ioclient.id).emit('message', newPictureTopic + ":" + picture2); 255 | eventSocket.to(ioclient.id).emit('message', newPictureTopic + ":" + picture1); 256 | 257 | ioclient.on('message', function(event) { 258 | var parts = event.split(":"); 259 | var topic = parts[0]; 260 | var value = parts[1]; 261 | if (topic == alarmStatusTopic) { 262 | mqttClient.publish(topic, value); 263 | } else if (topic == cameraCaptureTopic) { 264 | takePicture(mqttClient); 265 | } 266 | }); 267 | }); 268 | 269 | logEvent('Alarm active'); 270 | }; 271 | 272 | 273 | if (require.main === module) { 274 | var microAppFramework = require('micro-app-framework'); 275 | microAppFramework(path.join(__dirname), Server); 276 | } 277 | 278 | 279 | module.exports = Server; 280 | -------------------------------------------------------------------------------- /lib/page.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | <ALARM DASHBOARD TITLE> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 101 | 102 | 379 | 380 | 381 | 382 | 383 |
384 |
1
385 | 386 |
387 |
388 |
389 |
390 | 391 |
392 | ---- Disarmed ---- 393 |
394 | 395 | 396 | 397 | 416 | 433 | 434 |
398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 |
 arm
 picture
 
 
 
 
 
 
 
 
 
  
 showLog
414 |
415 |
417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 |
ZONES
zone1
zone2
zone3
zone4
zone5
zone6
zone7
zone8
431 |
432 |
435 | 436 | 437 | 438 | --------------------------------------------------------------------------------