Skip to content

Commit

Permalink
Added GeoHopper updates and concept of notification "events".
Browse files Browse the repository at this point in the history
  • Loading branch information
bdwilson committed Mar 18, 2015
1 parent e8b3d6e commit dd2751e
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 35 deletions.
45 changes: 27 additions & 18 deletions README.md
Expand Up @@ -41,6 +41,7 @@ well spent.
- Some method of calling the alert script (cronjob or via e-mail based procmail
trigger)
- Perl (and these modules: File::Basename File::Find File::stat Date::Manip Time::localtime LWP::UserAgent Astro::Sunrise Data::Dumper DBI)
- Optional iOS App [GeoHopper](https://itunes.apple.com/us/app/geohopper/id605160102?mt=8) helps identify if the user is home or away

I recommend installing [cpanminus](https://github.com/miyagawa/cpanminus) and
installing the Perl modules that way, or you can intall them via your distro
Expand Down Expand Up @@ -77,22 +78,25 @@ Then install the DB schema.
<pre>
$ mysql -u cam -pcam cam < cam.sql
</pre>
Now you can see an example of my data.
Now you can see an example of my data. ignoreHome and ignoreAway should be set
to 0 unless you want to ignore/suppress events if someone is either Home or
all users are Away. If you want to suppress events for the camera, then toggle
these to 1 instead of 0. These variable rely on the GeoHopper dependancy.
<pre>
mysql> select * from cameras;
+-----+-------------+---------+---------------------------------------------------------------+---------------------------------------+
| cid | location | enabled | snapshot_url | ignore_ranges |
+-----+-------------+---------+---------------------------------------------------------------+---------------------------------------+
| 1 | Front Porch | 1 | http://user:password@192.168.2.7/Streaming/channels/1/picture | |
| 2 | Garage | 1 | http://user:password@192.168.2.2/Streaming/channels/1/picture | 22-23,3:30-4:30,17:15-17:45,7:15-7:35 |
+-----+-------------+---------+---------------------------------------------------------------+---------------------------------------+
+-----+-------------+---------+---------------------------------------------------------------------+-----------------+------------+------------+
| cid | location | enabled | snapshot_url | ignore_ranges | ignoreHome | ignoreAway |
+-----+-------------+---------+---------------------------------------------------------------------+-----------------+------------+------------+
| 1 | Front Porch | 1 | http://user:password@192.168.2.7/Streaming/channels/1/picture | | 0 | 0 |
| 2 | Garage | 1 | http://user:password@192.168.2.2/Streaming/channels/1/picture | 22-23,3:30-4:30 | 0 | 0 |
+-----+-------------+---------+---------------------------------------------------------------------+-----------------+------------+------------+
mysql> select * from users;
+-----+-------+--------------+---------+------+-------------------+--------------------+---------------------+
| uid | user | authkey | enabled | week | pushoverApp | pushoverKey | lastNotify |
+-----+-------+--------------+---------+------+-------------------+--------------------+---------------------+
| 1 | admin | AAAAABBBAAAA | 1 | 1 | pushoverAppIDHere | pushoverAPIKeyHere | 2015-02-28 13:35:54 |
| 2 | user | BBBBAAAABBB | 1 | 0 | pushoverAppIDHere | pushoverAPIKeyHere | 2015-02-28 13:35:54 |
+-----+-------+--------------+---------+------+-------------------+--------------------+---------------------+
+-----+--------+-----------------+---------+-------+------+--------------------------------+--------------------------------+---------------------+--------+---------------------+
| uid | user | authkey | enabled | admin | week | pushoverApp | pushoverKey | lastNotify | isHome | homeTime |
+-----+--------+-----------------+---------+-------+------+--------------------------------+--------------------------------+---------------------+--------+---------------------+
| 1 | admin | AAAAABBBAAAA | 1 | 1 | 1 | pushoverAppIDHere | pushoverAPIKeyHere | 2015-03-17 21:24:47 | 1 | 2015-03-17 17:10:51 |
| 2 | user | BBBBAAAABBB | 1 | 0 | 0 | pushoverAppIDHere | pushoverAPIKeyHere | 2015-03-17 21:24:48 | 1 | 2015-03-17 14:55:54 |
+-----+--------+-----------------+---------+-------+------+--------------------------------+--------------------------------+---------------------+--------+---------------------+
</pre>
4. Create your users and cameras. Note the the cron script will convert
underscores (\_) to spaces for location names, so your FTP directory should be
Expand All @@ -108,10 +112,10 @@ the authkey in clear text as a GET. If you don't like it, send me a git pull :)
<pre>
$ mysql -u cam -pcam
mysql> use cam;
mysql> insert into cameras VALUES("","Front Porch","1","http://user:password@192.168.2.7/Streaming/channels/1/picture","");
mysql> insert into cameras VALUES("","Back Porch","1","http://user:password@192.168.2.7/Streaming/channels/1/picture","17-18,4:30-5:30");
mysql> insert into users VALUES("","user1","8675309","1","0","YOUR_PUSHOVER_APP_ID_HERE","YOUR_PUSHOVER_API_KEY_HERE","");
mysql> insert into users VALUES("","user2","C3PO","1","1","YOUR_PUSHOVER_APP_ID_HERE","YOUR_PUSHOVER_API_KEY_HERE","");
mysql> insert into cameras VALUES("","Front Porch","1","http://user:password@192.168.2.7/Streaming/channels/1/picture","",0,0);
mysql> insert into cameras VALUES("","Back Porch","1","http://user:password@192.168.2.7/Streaming/channels/1/picture","17-18,4:30-5:30",0,0);
mysql> insert into users VALUES("","user1","8675309","1","0","YOUR_PUSHOVER_APP_ID_HERE","YOUR_PUSHOVER_API_KEY_HERE","",0,"");
mysql> insert into users VALUES("","user2","C3PO","1","1","YOUR_PUSHOVER_APP_ID_HERE","YOUR_PUSHOVER_API_KEY_HERE","",0,"");
mysql> quit
</pre>
5. Copy config.php, index.php and image.php to the NVR_WEB location you
Expand All @@ -120,7 +124,7 @@ the Alias location where the images will be surfaced from (i.e. where your FTP
server is writing files). Set *ip_net* to be a regex to match your local IP
network if you want to bypass auth from that network. If you don't want to
bypass auth on your local net, set this to be */^256.256.256.\d+$/*.
6. Edit nvr_alert.pl and do the following:
6. Edit nvr_alert.pl and modify/point to nvr_alert.cfg do the following:
* Configure your *lat* and *long* to correctly configure sunrise/sunset
times. (maps.google.com) can help you if you look for your address then get the
lat/long from the URL.
Expand All @@ -143,6 +147,10 @@ the Internet.
nofications. This is mainly for if the job is run by an external script (such
as procmail or snmptrap). If you're running this from cron, just set this to
the same number of minutes the cronjob is run as.
* *geohopper* options should be self explanitory. You need to install the
iOS app, create a Web Service item that points to your
url/geohopper.php?auth=YOURAUTHID. Next, create a location called "Home", then
link the Web Service entry to your "Home" location.
* database info should match config.php and the info you used to create your
database and user from the initial steps.
7. Make sure you can get to index.php without any errors. You can always
Expand Down Expand Up @@ -179,6 +187,7 @@ run nvr_alert.pl by hand from the command line.
/config.php
/image.php
</pre>
5. Check your log.

Bugs/Contact Info
-----------------
Expand Down
94 changes: 94 additions & 0 deletions cam.sql
@@ -0,0 +1,94 @@
-- phpMyAdmin SQL Dump
-- version 4.0.10deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Mar 07, 2015 at 10:15 PM
-- Server version: 5.5.41-0ubuntu0.14.04.1
-- PHP Version: 5.5.9-1ubuntu4.6

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Database: `cam`
--

-- --------------------------------------------------------

--
-- Table structure for table `cameras`
--

CREATE TABLE IF NOT EXISTS `cameras` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`location` varchar(12) NOT NULL,
`enabled` int(11) NOT NULL DEFAULT '1',
`snapshot_url` varchar(200) NOT NULL,
`ignore_ranges` varchar(100) NOT NULL,
`ignoreHome` int(11) NOT NULL,
`ignoreAway` int(11) NOT NULL,
PRIMARY KEY (`cid`),
UNIQUE KEY `name` (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

-- --------------------------------------------------------

--
-- Table structure for table `images`
--

CREATE TABLE IF NOT EXISTS `images` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image` varchar(500) NOT NULL,
`date` datetime NOT NULL,
`location` varchar(25) NOT NULL,
`notified` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`image`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `image` (`image`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14221 ;

-- --------------------------------------------------------

--
-- Table structure for table `suppress`
--

CREATE TABLE IF NOT EXISTS `suppress` (
`authkey` varchar(15) NOT NULL,
`expiration` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`user` varchar(12) NOT NULL,
`authkey` varchar(20) NOT NULL,
`enabled` int(1) NOT NULL DEFAULT '1',
`admin` int(11) NOT NULL DEFAULT '0',
`week` int(1) NOT NULL DEFAULT '1',
`pushoverApp` varchar(30) NOT NULL,
`pushoverKey` varchar(30) NOT NULL,
`lastNotify` datetime NOT NULL,
`isHome` int(11) DEFAULT '0',
`homeTime` datetime NOT NULL,
UNIQUE KEY `uid` (`uid`),
UNIQUE KEY `user` (`user`),
KEY `uid_2` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
45 changes: 45 additions & 0 deletions geohopper.php
@@ -0,0 +1,45 @@
<?php

require_once('config.php');

#ini_set('display_startup_errors',1);
#ini_set('display_errors',1);
#error_reporting(-1);


$auth=0;

if ($_REQUEST['auth'] && (!preg_match('/^[a-zA-Z0-9]+$/',$_REQUEST['auth']))) {
exit;
}
$token=$_REQUEST['auth'];
if ($token) {
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$stmt = $conn->prepare("select count(uid),week,admin from users where authkey=? and enabled=1");
$stmt->bind_param("s", $token);
$stmt->execute();
$stmt->bind_result($auth,$week,$is_admin);
$stmt->fetch();
}

if ($auth<1) {
exit;
}

$data = json_decode(file_get_contents('php://input'));

if (preg_match('/Home/',$data->location)) {
if ($data->event == "LocationEnter") {
$location = "1";
} else {
$location = "0";
}
}

if ($location >= 0) {
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$stmt = $conn->prepare("update users set isHome=?,homeTime=NOW() where authkey=?");
$stmt->bind_param("ss", $location,$token);
$stmt->execute();
}
?>
96 changes: 81 additions & 15 deletions index.php
Expand Up @@ -16,6 +16,9 @@
if ($_REQUEST['auth'] && (!preg_match('/^[a-zA-Z0-9]+$/',$_REQUEST['auth']))) {
exit;
}
if ($_REQUEST['event'] && (!preg_match('/^[0-9]+$/',$_REQUEST['event']))) {
exit;
}
if (($_REQUEST['snapshot'] > 0) && (!preg_match('/^[0-9]+$/',$_REQUEST['snapshot']))) {
exit;
}
Expand All @@ -24,10 +27,10 @@

if ($token) {
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$stmt = $conn->prepare("select count(uid),week from users where authkey=? and enabled=1");
$stmt = $conn->prepare("select count(uid),week,admin from users where authkey=? and enabled=1");
$stmt->bind_param("s", $token);
$stmt->execute();
$stmt->bind_result($auth,$week);
$stmt->bind_result($auth,$week,$is_admin);
$stmt->fetch();
}

Expand Down Expand Up @@ -91,6 +94,20 @@
echo "<br><br>";

}

if ($is_admin && $auth && $_REQUEST['admin'] == 1) {
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$query="select image,date from images where DATE_SUB(NOW(),INTERVAL $last) <= date order by date desc";
$stmt = $conn->prepare($query);
#$stmt->bind_param("s", $last);
$stmt->execute();
$stmt->bind_result($image,$date);
#$stmt->fetch();
while($stmt->fetch()){
#echo "$image $date\n<br>";
$count++;
}
}
if ($suppress && $token) {
?>
<center> Suppress alerts for: [
Expand All @@ -109,20 +126,25 @@
?>
<title>Video Camera Monitor</title>
<center>
[ <a href="index.php?time=suppress&auth=<?=$_REQUEST['auth']?>">Suppress Alerts</a> |
<a href="index.php?auth=<?=$_REQUEST['auth']?>">Last 10 Minutes</a> |
<a href="index.php?time=hour&auth=<?=$_REQUEST['auth']?>">Last Hour</a> |
<a href="index.php?time=half&auth=<?=$_REQUEST['auth']?>">Last 12 Hours</a> |
<a href="index.php?time=day&auth=<?=$_REQUEST['auth']?>">Last 24 Hours</a>
[ <a href="index.php?events=1&auth=<?=$_REQUEST['auth']?>">Events</a> |
<a href="index.php?time=suppress&auth=<?=$_REQUEST['auth']?>">Suppress Alerts</a> |
<a href="index.php?auth=<?=$_REQUEST['auth']?>">10 Minutes</a> |
<a href="index.php?time=hour&auth=<?=$_REQUEST['auth']?>">Hour</a> |
<a href="index.php?time=half&auth=<?=$_REQUEST['auth']?>">12 Hours</a> |
<a href="index.php?time=day&auth=<?=$_REQUEST['auth']?>">24 Hours</a>
<?php
if ($week == 1) {
?>
| <a href="index.php?time=week&auth=<?=$_REQUEST['auth']?>">Last Week</a> ]
| <a href="index.php?time=week&auth=<?=$_REQUEST['auth']?>">Last Week</a>
<?php
} else {
echo " ]";
}
if ($is_admin == 1) {
?>
| <a href="index.php?admin=1&auth=<?=$_REQUEST['auth']?>">Admin</a>
<?php
}
?>
]
<?php
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$stmt = $conn->prepare("select cid,location from cameras where enabled=1 and snapshot_url != ''");
Expand All @@ -148,18 +170,62 @@

if ($snapshot > 0) {
echo "<a border=0 href=image.php?&snapshot=" . $snapshot . "&auth=". $_REQUEST['auth'] . "><center><img width=100% src=image.php?snapshot=". $snapshot . "&auth=" . $_REQUEST['auth'] . "></a>";
} else if ($_REQUEST['events'] == 1) {
$count=0;
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$query="select distinct(eventId) from images where 1 order by date desc";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bind_result($eventId);
while($stmt->fetch()){
$count++;
$conn2 = new mysqli($db_server, $db_username, $db_password, $db_database);
$query2="select max(date),min(date),count(id),UNIX_TIMESTAMP(max(date)),UNIX_TIMESTAMP(min(date)) from images where eventId=?";
$stmt2 = $conn2->prepare($query2);
$stmt2->bind_param("s", $eventId);
$stmt2->execute();
$stmt2->bind_result($max,$min,$ecount,$unix_max,$unix_min);
if ($count == 1) {
?><table width=40% border=1 cellspacing=0 cellpadding=0><tr>
<td><center><b>EventID</td>
<td><center><b>Number of Images</td>
<td><center><b>Start Time</td>
<td><center><b>Stop Time</td>
<td><center><b>Seconds</td></tr>
<?php
}
# echo "$unix_max $unix_min ($secs)<br>";
while($stmt2->fetch()){
$eurl = "?event=" . $eventId . "&auth=" . $_REQUEST['auth'];
$secs=$unix_max-$unix_min;
?><tr><td align=center><a border=0 href="<?=$eurl?>"><?=$eventId?></a></td>
<td><center><?=$ecount?></td><td><center><?=$min?></td><td><center><?=$max?></td>
<td><center><?=$secs?></td></tr>
<?php
}
}
} else {
$count=0;
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$query="select max(eventId) from images";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bind_result($eventId);
# if someone has viewed the images on the web, mark them as being
# notified.
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$stmt = $conn->prepare("update images set notified=1 where notified=0");
$stmt = $conn->prepare("update images set notified=1,eventId=? where notified=0");
$stmt->bind_param("s", $eventId);
$stmt->execute();
#
$conn = new mysqli($db_server, $db_username, $db_password, $db_database);
$query="select image,date from images where DATE_SUB(NOW(),INTERVAL $last) <= date order by date desc";
$stmt = $conn->prepare($query);
#$stmt->bind_param("s", $last);
if ($_REQUEST['event']) {
$query="select image,date from images where eventId=? order by date desc";
$stmt = $conn->prepare($query);
$stmt->bind_param("s", $_REQUEST['event']);
} else {
$query="select image,date from images where DATE_SUB(NOW(),INTERVAL $last) <= date order by date desc";
$stmt = $conn->prepare($query);
}
$stmt->execute();
$stmt->bind_result($image,$date);
#$stmt->fetch();
Expand Down

0 comments on commit dd2751e

Please sign in to comment.