Project showcase
Smart Alarm: An Infinite Range Car Alarm

Smart Alarm: An Infinite Range Car Alarm © CC BY-SA

What if someone breaks in to your car when you aren't around? Smart Alarm will help with that.

  • 1,851 views
  • 1 comment
  • 10 respects

Components and supplies

Apps and online services

About this project

What is Smart Alarm?

Car alarms are useful when your car is on the street outside your house or office. But what if your car is in an airport parking lot, thousands of miles away. Well that's where Smart Alarm comes in. When engaged, Smart Alarm uses the DPS310 pressure sensor to detect sharp disruption in pressure, for example: a door being opened, or window being broken. It then sends an alert to your cell phone with the current date and time. It could also be set up to start the recording of a rear facing dash cam when triggered.

How does it work?

Smart Alarm runs on an Arduino outfitted with a DPS310 pressure sensor and a GSM shield. The pressure sensor is there to detect pressure events, such as a window or door being opened/closed. The GSM shield allows the device to actually connect to the internet, and the rest of the service.

Smart Alarm sends a request to a web server every time it detects a pressure change event that breaks its threshold. If the user has engaged the alarm with the android app or the web app, they will receive an alert when a door/window opening is detected. If they have not engaged the alarm, these events will still be recorded and accessible via the web app, but the user will not be alerted in real time.

However, if the Arduino detects the car alarm has been set off, even if no door/window has been opened, it will alert the user, regardless of whether or not they have engaged the alarm.

Detecting Doors and Windows

Doors and Windows are detected as opened when a sharp change in pressure is detected by the DPS310. When this happens, the device sends a POST request to the web server, which then dispatches notifications accordingly.

Back-end:

The back-end is a Node.JS application running on a web server. It uses express to handle requests, and uses the following routes:

PLEASE NOTE: This is currently a prototype, and contains no security other than not revealing the server address to others. Use this server software with caution.

GET /

This route leads to the main interface for the application. On this page, the user can enable/disable Smart Alarm, and view the event logs.

In the screenshot above, you can see the most recent event is red. An event will appear as red (urgent) when a door/window is opened while Smart Alarm is armed, or if the car alarm goes off. If the car alarm goes off, the event will appear red no matter what.

GET /arm

This route will enable/disable Smart Alarm alerts when accessed.

POST /createAlert

This route is used by the Arduino to create alerts. The post body contains 2 pieces of information: time and urgency. The time is a simple timestamp, the urgency is determined on whether or not the actual car alarm is going off. If the user has alerts enabled with /arm, they will be alerted to all events. If they do not, they will only be alerted to urgent events.

Other Information:

  • I use NeDB for data storage, as it is lightweight and I am not storing any substantial amount of data.
  • I use fcm-push for firebase cloud messaging integration for the android app.
  • I use body-parser to parse post requests from the device.
  • I use ejs templates to render the web page.

Android App:

The Android App allows you to receive alerts on your mobile device when the Smart Alarm has been tripped. You can also Arm/Disarm the alarm from the app.

When Smart Alarm is enabled, you will receive push notifications for every event:

Notifications are handled using Firebase Cloud Messaging.

Demo:

Here is a video of Smart Alarm in action.

It gets a bit loud, a car alarm goes off.

Server Setup

To begin you will need to install Node.JS 6.11

After you have done that, download all the code from the attachments of this project, and lay out the files in a folder as follows:

  • /index.js
  • /package.json
  • /views/elements/header.ejs
  • /views/pages/index.ejs

After you have done this, navigate to the root of the folder in a command prompt (Node JS command prompt on Windows) and run:

npm install

Next, open up index.js and replace YOUR_SERVER_KEY_HERE on line 26 with the server key from your Firebase project. This can be found by going to console.firebase.google.com, navigating to your project, clicking the settings icon next to the Overview button, and clicking cloud messaging.

After you have done this, you are ready to run the server software with

node 

Android App Setup

To set up the android app, first download the zip file containing the source code, extract it, and import it into Android Studio.

After you have done this, go to console.firebase.google.com and click add project.

You can name it whatever you want, but after you have created it, press add firebase to your android app.

Enter the package name com.tommy.smartalarm, unless you have renamed it.

Click register app, then follow the instructions on the next page to install the new google-services.json it provides. (Place it in the app folder in the project)

The next page asks you to add the Firebase SDK, but that has already been done by me, so you do not have to.

The last thing you must do to finish setting up the app for your use is change the IP address mentions in MainActivity.java to your own computer IP address, or the server IP address if you are using one.

That's it! Just press build and install it on your device with the Run button and you are good to go! It should be able to receive push notifications from the node app as well as arm/disarm the alarm.

Code

index.jsJavaScript
Main file for the web server.
This file should be placed at /index.js
/*
	This application is the back-end for Smart Alarm.
	
	Licensed under CC BY-SA 4.0
*/

//Set port
const port = 80;

//Set up express
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());

//Variables
var armed = false
var Datastore = require('nedb');
var db = new Datastore({ filename: 'data/events.db', autoload: true });


//Set up firebase cloud messaging
var FCM = require('fcm-push');

var serverKey = 'YOUR_SERVER_KEY_HERE';
var fcm = new FCM(serverKey);

//Set up ejs, used to render the index page.
app.set('view engine', 'ejs');

app.get('/', function (req, res) {
	db.find({}, function (err, docs) {
  		res.render('pages/index.ejs', {armed: armed, events: docs})
  	});
})

app.get('/arm', function (req, res) {
  	console.log("Armed")
  	db.insert({message: "Smart Alarm Armed", time: Math.floor( Date.now() / 1000 ), urgent: (req.body.urgent == "false")})
  	armed = true
  	res.redirect('/')
})

app.get('/disarm', function (req, res) {
	console.log("Disarmed")
	db.insert({message: "Smart Alarm Disarmed", time: Math.floor( Date.now() / 1000 ), urgent: (req.body.urgent == "false")})
	armed = false
  	res.redirect('/')
})

app.post('/createAlert', function (req, res) {
	console.log(JSON.stringify(req.body))
	var sent = false
	var message = {
	    to: '/topics/carAlerts', // required fill with device token or topics
	    notification: {
	        title: 'Smart Alarm Alert',
	        body: req.body.message,
	        sound: 'default'
	    },
	    data: {
	    	alert: "Alarm",
	    	body: req.body.message
	    }
	};
	if (armed) {
		fcm.send(message, function(err, response){
		    if (err) {
		        console.log("Error sending firebase message.");
		    } else {
		        console.log("Successfully sent firebase message with response: ", response);
		    }
		});
		sent = true;
		req.body.urgent = "true"
	}
	db.insert({message: req.body.message, time: Math.floor( Date.now() / 1000 ), urgent: (req.body.urgent == "true")})
	if (req.body.urgent == "true" && !sent) {
		fcm.send(message, function(err, response){
		    if (err) {
		        console.log("Error sending firebase message.");
		    } else {
		        console.log("Successfully sent firebase message with response: ", response);
		    }
		});
	}
	res.send("Success.")
});

app.listen(port, function () {
  console.log('SmartAlarm back-end online. Active on port: '+port)
})
events.dbJavaScript
This is an example database file for the back-end.
You do not need to copy this if you are setting up your own version. This is just a sample.
{"message":"Smart Alarm Armed","time":1505688522,"urgent":false,"_id":"1PpYQecd1u0gQz8C"}
{"message":"Smart Alarm Disarmed","time":1505688548,"urgent":false,"_id":"IJxS35yFlmMqZUP8"}
{"message":"Smart Alarm Armed","time":1505688550,"urgent":false,"_id":"oNOzPeQTw8sZOcZY"}
{"message":"Smart Alarm Disarmed","time":1505688551,"urgent":false,"_id":"uBQsAd39z37Vexyw"}
{"message":"Smart Alarm Armed","time":1505688553,"urgent":false,"_id":"0Fs2AqOLhp3kKHHt"}
{"message":"Smart Alarm Armed","time":1505688568,"urgent":false,"_id":"iTmNeoUZiIC1p31s"}
{"message":"Smart Alarm Disarmed","time":1505688594,"urgent":false,"_id":"KO2q9SkrFA8rxGPJ"}
{"message":"Smart Alarm Armed","time":1505688595,"urgent":false,"_id":"Decuq1WT0wEw6t1u"}
{"message":"Smart Alarm Disarmed","time":1505688596,"urgent":false,"_id":"GIG1kRi91ZX1wsly"}
{"message":"Smart Alarm Armed","time":1505688597,"urgent":false,"_id":"ABVWo555znDbxoHB"}
{"message":"Smart Alarm Disarmed","time":1505688763,"urgent":false,"_id":"t3nTPQpfWbBFS1ZS"}
{"message":"Smart Alarm Armed","time":1505688802,"urgent":false,"_id":"9RUWqMGA9o3aE7Nx"}
{"message":"A Door/Window has been opened.","time":1505688886,"urgent":true,"_id":"fgHd2MemZv7WmX8x"}
{"message":"A Door/Window has been opened.","time":1505688934,"urgent":true,"_id":"5VTM373TgSw2BTMl"}
{"message":"A Door/Window has been opened.","time":1505688970,"urgent":true,"_id":"6giuTNrl4Y7DGchq"}
{"message":"A Door/Window has been opened.","time":1505689060,"urgent":true,"_id":"FQe2Bw74DmFwfOec"}
{"message":"Alarm has been set off!","time":1505689241,"urgent":true,"_id":"cFyZDbdZU2ki6mrS"}
{"message":"Smart Alarm Disarmed","time":1505689438,"urgent":false,"_id":"fTe7z1WeWIvh71nZ"}
{"message":"Smart Alarm Armed","time":1505689460,"urgent":false,"_id":"1c5HryJaVtrhUIOR"}
{"message":"Smart Alarm Disarmed","time":1505689466,"urgent":false,"_id":"zNukVyw9GJsYuKpy"}
{"message":"Smart Alarm Armed","time":1505689478,"urgent":false,"_id":"LDhlvCW0U7t0Lm3e"}
{"message":"Smart Alarm Disarmed","time":1505689483,"urgent":false,"_id":"nD95ligNk0GEoIGn"}
{"message":"Smart Alarm Armed","time":1505689493,"urgent":false,"_id":"dFecknNsFJTvHqSj"}
{"message":"Smart Alarm Disarmed","time":1505689496,"urgent":false,"_id":"i5Ja0k6LirEI0Y4G"}
{"message":"Smart Alarm Armed","time":1505689508,"urgent":false,"_id":"THVILG5Xx0hSVQgv"}
{"message":"Smart Alarm Disarmed","time":1505689511,"urgent":false,"_id":"jU1HbJ7KNQYUSrps"}
{"message":"Alarm has been set off!","time":1505689520,"urgent":true,"_id":"bfjVkH1jvK49tilk"}
{"message":"A Door/Window has been opened.","time":1505689566,"urgent":false,"_id":"H9OgeW6TZ9zb0Z8E"}
{"message":"A Door/Window has been opened.","time":1505689681,"urgent":false,"_id":"jmMFf95FjbGv8IEl"}
{"message":"Smart Alarm Armed","time":1505689749,"urgent":false,"_id":"X73X4XkMQR1WCQ0s"}
{"message":"A Door/Window has been opened.","time":1505689757,"urgent":true,"_id":"8d4vFPZzASKZpzdz"}
{"message":"Smart Alarm Disarmed","time":1505689766,"urgent":false,"_id":"e022m0vCGgHd6OdC"}
{"message":"Smart Alarm Armed","time":1505689781,"urgent":false,"_id":"YmmUZxUv1L9L3Dif"}
{"message":"A Door/Window has been opened.","time":1505689789,"urgent":true,"_id":"5XSeQyFMn5zyH0Mw"}
{"message":"Smart Alarm Disarmed","time":1505689814,"urgent":false,"_id":"sQ1qFjB4XZbIBIbJ"}
header.ejsHTML
Header for website.
Should be placed at /views/elements/header.ejs
<!--

	Smart Alarm Header

-->
<title>Smart Alarm</title>

<!-- Import Bootstrap and Bootstrap JS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
SmartAlarm.zip - Android AppJava
This is the source for the Android application. To make it work with your system, you will need to change the IP address in the code. The IP is set in MainActivity.java

You are free to use this code without any attribution. But idk why you would want to.
No preview (download only).
index.ejsHTML
The web UI.
Should be placed at /views/pages/index.ejs
<!--

	Smart Alarm Index Page

-->

<!DOCTYPE html>
<head>
	<% include ../elements/header.ejs %>
</head>
<body>
	<!-- Navbar -->
	<nav class="navbar justify-content-between">
		<a class="navbar-brand">Smart Alarm</a>
		
		<form class="form-inline">
			<% if (armed) { %>
				<label style="padding-right: 5px;">Currently Armed</label>
				<a href="/disarm" class="btn btn-outline-success">Disarm</a>
			<% } else { %>
				<label style="padding-right: 5px;">Currently Disarmed</label>
				<a href="/arm" class="btn btn-outline-success">Arm</a>
			<% } %>
		</form>
	</nav>


	<!-- Main Container -->
	<div class="container-fluid">
		
		<div class="card">
			<div class="card-header">
				Event Log
			</div>

			<div class="card-body">
				<table class="table">
					<thead>
						<tr>
							<th>#</th>
							<th>Time</th>
							<th>Event</th>
						</tr>
					</thead>
					<tbody>
						<% events.sort(function(a,b) {
							return (b.time - a.time)
						}); 

						for (var i=0; i < events.length; i++) { %>
						<%
						var d = new Date(0);
						d.setUTCSeconds(events[i].time)
						%>
						<tr <% if (events[i].urgent) { %> style="background: red; color: white;" <% } %>>
							<th scope="row"><%= i+1 %></th>
							<td><%= d %></td>
							<td><%= events[i].message %></td>
						</tr>
						<% } %>
					</tbody>
				</table>
			</div>
		</div>

	<!-- End of Main Container -->
	</div>
</body>
package.jsonJSON
The package.json file, after copying all other files to their appropriate directories, run npm install in the root.
This file should be placed at /package.json
{
  "name": "smart-alarm",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "SEE LICENSE IN index.js",
  "dependencies": {
    "body-parser": "^1.18.1",
    "ejs": "^2.5.7",
    "fcm-push": "^1.1.2",
    "express": "^4.15.4",
    "nedb": "^1.8.0"
  },
  "devDependencies": {},
  "description": ""
}

Schematics

Flow of communications between all aspects of the system.
This diagram shows the flow of data between all components in the system.
Comflow t9bk4kxvmj

Comments

Add projectSign up / Login