Thursday, December 8, 2016

Raspberry Pi Security Camera Viewer

Most high-definition televisions have a "Picture-in-Picture" feature that is useless; if you are watching a HD input the PIP window can only display a low-resolution input such as RF or Composite SDTV.  Furthermore the sole Composite video input is often combined with the Component video input which may already be used by your older video game console. 

What's left?  I'll show you how to use your HDTV's coaxial cable TV RF input to view up to four network security cameras in the PIP window so you can keep an eye on your perimeter while watching something else.

We'll use the Raspberry Pi to automatically scan your network for up to four RTSP cameras and display them in a 1x1 or 2x2 grid through its composite video output fed to an RF modulator connected to your TV. 

In fact, if you still have unused "cable TV" coaxial cable running all over your home you can use it to send the camera grid to multiple televisions.  You just need to tune each TV to the RF modulator channel.  Just make sure your coaxial cables don't actually connect to the cable TV company!


The RF Modulator


I use a Channel Vision E Series E1200 but any RF modulator will do.  These take a composite video input and output it on an RF cable channel of your choice (usually between 2 and 13)

Using the correct A/V cable for the Raspberry Pi 3 is very important.  Please read this article on how cables that appear to be similar can have very different pinouts.

I have tested this Zune cable from Amazon and it works fine with the Raspberry Pi.

Camera configuration


This project requires that all your network security cameras support RTSP and use the same username, password and RTSP url suffix. 

I've been pretty happy with the Amcrest IP2M-842E Outdoor 1080P POE Security Camera available from Amazon in Black or White.  I'll assume you know how to make and run CAT6 cabling and know these need to be plugged into a POE switch or separate POE power injectors.

When you set these up using Amcrest's app be sure to configure them with the same username and password.  They all have the same RTSP url format:

rtsp://username:password@ipaddress/cam/realmonitor?channel=1&subtype=1

Subtype 1 = SD
Subtype 0 = HD

Since we will be outputting SD from the Pi there's no need to use the HD streams.  Use subtype=1.

About Network Video Recorders (NVRs)


Using RTSP streams from your cameras should not prevent you from simultaneously using an NVR (such as the one made by Amcrest) to record camera video when motion is detected in predefined zones.  This project just gives purpose to the PIP feature on your TV whether you use an NVR or not.

While most NVRs can output a 2x2 (or better) grid for monitoring your cameras, I've only seen HDMI outputs on them.  That means I can't use the NVR with the PIP feature on my TV.

I suppose the alternative to this project is to either get a TV that supports HDMI on PIP or try to find an HDMI to Composite video converter.  But I'd still need an RF modulator anyhow.  And this means the NVR can be somewhere else, secured against theft.

Raspberry Pi 3 configuration


First, follow my initial configuration guide.

Install nmap, omxplayer and screen:

sudo apt-get install nmap omxplayer screen

Edit /boot/config.txt:

sudo nano /boot/config.txt

Comment out (add # in front) ALL occurrences of hdmi_force_hotplug - it may be in there more than once!
Add overscan_scale=1 and gpu_mem=128
Uncomment sdtv_mode and set it to 0
# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment for composite PAL
sdtv_mode=0

# NOOBS Auto-generated Settings:
#hdmi_force_hotplug=1

# CCTV Settings
gpu_mem=128
overscan_scale=1
With these settings if the Pi boots up and does not detect an HDMI monitor connected it will use the composite video output.

Create /home/pi/cctv:

nano /home/pi/cctv

Type in (or copy and paste) this bash script, substituting the username and password used by your cameras:

Then grant execute permissions:

chmod +x /home/pi/cctv

Test the script by running it manually, specifying the horizontal and vertical resolution that works best for you:

./cctv 640 480

To configure the Pi to run the script on boot, add this line to /etc/rc.local before exit 0:

/home/pi/cctv 640 480

Wednesday, December 7, 2016

Raspberry Pi 3 initial configuration

Here are the steps I use when setting up a new Raspberry Pi 3.

I usually get an 8GB microSD card but depending on the project I've gone larger.  I like the SanDisk Extreme microSDHC UHS-I. 

Make sure you have the proper power supply for the Pi 3.  I believe it needs to be at least 2.5 amps. 

Download the NOOBS zip file from the Raspberry Pi .org site and unzip its contents into the microSD card from your PC.  The cards I buy are preformatted FAT32 which works fine for NOOBS.

Slip the microSD card into the Pi 3 and boot it up.  If you press the w key you can connect to your home wifi network in order to view the complete list of installation options.  You need to do this so you can select the Lite version of the Raspbian OS, which is my preference.

After the installation is completed and the Pi has rebooted, log in as user pi with password raspberry.

Change the root password to raspberry so you don't forget it (in case you need to su)

sudo passwd root

Go through the locale & internationalization options in raspi-config to set your timezone, keyboard, country, etc.

sudo raspi-config

Configure wpa_supplicant.conf so the Pi connects to your home wifi network on boot:

Setting WiFi up via the command line

Reboot the Pi:

sudo reboot

Update the Pi:

sudo apt-get update
sudo apt-get upgrade


Here's another way to change the keyboard configuration to US (the Pi defaults to a UK configuration):

sudo dpkg-reconfigure keyboard-configuration

Edit /etc/rsyslog.conf:

sudo nano /etc/rsyslog.conf

Comment out these lines at the bottom:
#daemon.*;mail.*;\
#       news.err;\
#       *.=debug;*.=info;\
#       *.=notice;*.=warn       |/dev/xconsole
Set the timezone of the Pi.  Run the next command from the console rather than over SSH:

sudo dpkg-reconfigure tzdata

Older Pi kernel versions defaulted power management to on which in conjunction with another setting may result in the integrated wifi interface going to sleep - most inconvenient when trying to manage the prop over wifi!

The apt-get update and upgrade steps performed above should upgrade the kernel.  You can check your kernel version by issuing the following command:

sudo uname -a

As of this writing my kernel version is 4.4.34-v7+ #930 SMP.

You can check the power save mode of the wifi interface using the following command:

sudo iw wlan0 get power_save

If it says power save mode is On then you can try adding this line to /etc/network/interfaces after the wlan0 section:

post-up iw wlan0 set power_save off

Then reboot and check the power save mode of the interface again to confirm it is now off.  If you ever see this mode change back to On try searching the internet to solutions for the power management issue and try different solutions until it is resolved.  Following the above steps resolved the issue for me. 

Friday, December 2, 2016

Manage animatronic props from a wireless tablet, Part 2

Step 2:  Install a suitable web server and server-side application framework


(continued from Part 1)

Rather than Apache I went with NGINX for the web server.  Since I want to develop the web application in Python 3, I selected Django.  In order to work with Django, NGINX needs uWSGI.  I also want to use PostgreSQL as the database.

sudo apt-get install nginx

sudo apt-get install uwsgi
sudo apt-get install python3
sudo apt-get install python3-rpi.gpio
sudo apt-get install uwsgi-plugin-python3
sudo apt-get install python3-django

sudo apt-get install postgresql
sudo apt-get install python3-psycopg2

Breakdown of our "stack":

  1. NGINX is the web server
  2. uWSGI is the interface between the web server and the web application framework
  3. Django is the web application framework
  4. Python is the application programming language
  5. PostgreSQL is the database
Throughout this article I may talk about "editing a file" and I may or may not tell you how to do this.  I prefer to use the nano editor.  The syntax is nano followed by the path & filename.  If you are not root you will need to add the sudo command in front.

NGINX configuration


Since users will connect from a tablet such as an iPad, once they connect to the Raspberry Pi in wifi access point mode we want to redirect all traffic to the application.

Since many of the bookmark URLs in Safari (such as Google, Apple, etc.) start with https we need to configure NGINX to allow https over port 443 in addition to regular http over port 80.

First we generate a self-signed SSL certificate.

https://dracoblue.net/dev/https-nginx-with-self-signed-ssl-certificate/

You'll need to read up on how to configure an NGINX site.  Here's how I configured mine:
server {
listen 80;
listen 443 ssl;
if ($scheme = https) {return 302 http://$server_addr/prophome.html;}
server_name localhost;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
access_log /var/log/nginx/asp.access.log;
error_log /var/log/nginx/asp.error.log;
location / {
     root /var/www/asp;
     index prophome.html;
     error_page 404 302 http://$server_addr/prophome.html;
     }
location /app {
     include         /etc/nginx/uwsgi_params;
     uwsgi_pass      unix:/var/uwsgi/propos.sock;
     uwsgi_param     UWSGI_SCHEME $scheme;
     uwsgi_param     SERVER_SOFTWARE nginx/$nginx_version;
     }
}
The scheme and error_page lines redirect the user's browser to the application page prophome.html which is just a basic "Hello World" html file we create for initial testing. 

Eventually prophome.html will be changed to the real application page.

This makes connecting simple; the user just clicks any icon in their Safari bookmarks and does not have to remember any special URL to access the application.

uWSGI configuration


In /usr/share/nginx/propos/ create a wsgi.py test program:
def application(environ, start_response):
     start_response('200 OK', [('Content-Type', 'text/html')])
     return [b"<h1 style="color: blue;">Hello There!</h1>"]
The b after return[ is required in Python3. Without it you will not get a response.

In /etc/uwsgi/apps-available, create an ini file for the application.

sudo nano /etc/uwsgi/apps-available/propos.ini

The file should look like this:
[uwsgi]
module = wsgi:application
chdir = /usr/share/nginx/propos/
python-path = /usr/share/nginx/propos
socket = /var/uwsgi/propos.sock
chown-socket = www-data
chmod-socket = 666
enable-threads = true
master = true
plugins-dir = /usr/lib/uwsgi/plugins
plugin = python34,http
uid = www-data
gid = www-data
vacuum = true
die-on-term = true
manage-script-name = true
Create a symbolic link for this file in ../apps-enabled:

sudo ln -s /etc/uwsgi/apps-available/propos.ini /etc/uwsgi/apps-enabled/propos.ini

Then restart uwsgi:

sudo service uwsgi restart

Then you might as well restart NGINX:

sudo service nginx restart

NGINX communicates with uWSGI over a unix socket which is specified in both config files (/var/uwsgi/propos.sock) - you may need to create the directory and/or adjust the permissions.

If you go to http://(pi address)/app you should see the test output:

Hello There!


If you see that, uWSGI is working correctly.  We will be reconfiguring propos.ini to work with a Django project in the next section.

Django configuration


Create a new Django project.  In this example I will use /home/pi/propos.

cd /home/pi
(do not create a propos directory in /home/pi, django admin will do that for you automatically)

django-admin startproject propos

Django will create the propos directory containing manage.py and a propos subdirectory containing other .py files.

Reconfigure uWSGI to point to this Django application:

sudo nano /etc/uwsgi/apps-available/propos.ini

Edit the file to look like this:
[uwsgi]
chdir = /home/pi/propos/
module = propos.wsgi:application
socket = /var/uwsgi/propos.sock
chown-socket = www-data
chmod-socket = 666
enable-threads = true
master = true
plugins-dir = /usr/lib/uwsgi/plugins
plugin = python34,http
uid = www-data
gid = www-data
vacuum = true
die-on-term = true
manage-script-name = true
Restart uWSGI:

sudo service uwsgi restart

After the service fully restarts If you go to http://(pi address)/app you should see something like this:



If you see that then uWSGI and Django are working correctly!

Thursday, November 10, 2016

Manage animatronic props from a wireless tablet, Part 1

Moving up to a Raspberry Pi from the Arduino provides several benefits.  The Pi is basically a computer which allows us to do a whole lot more.  We have more choices in programming languages, the ability to play high quality video and audio files, and with the Pi 3's integrated wireless network interface we can even turn the Pi into an access point and configure the prop via an iPad (or other wireless tablet) using a web interface.

Project Steps
  1. Configure a Pi 3 as a wireless access point that redirects all URLs to its own IP address and advertise a prop name over the network
  2. Install a suitable web server and server-side application framework (such as Python or Mono)
  3. Develop a prop control program that allows users to "program" prop logic using a web browser.  Pi GPIO pins can be referred to by name, On or Off can be defined as High or Low, video playback, audio playback, delays, if/then, looping, etc.  Optionally provide a way to change the wifi channel via the web interface, change the operating mode from access point to join an existing wifi network, and change other network settings
  4. Research audio/video capabilities (crossfading, looping, transition from static image to video on trigger, etc.)
  5. Interface 5v relay boards with Pi 3.3v GPIO
  6. Interface an audio amplifier board over i2c
  7. Build optoisolated triggers for Insteon, motion and IR beam-break sensors

Step 1:  Configure a Pi 3 as a wireless access point that redirects all URLs to its own IP address and advertise a prop name over the network


First follow my initial configuration guide for setting up a new Raspberry Pi 3.

Set the hostname of the prop to "NewProp"

https://thepihut.com/blogs/raspberry-pi-tutorials/19668676-renaming-your-raspberry-pi-the-hostname

Configure the DHCP client to register as "NewProp":
  1. Edit /etc/dhcp/dhclient.conf
  2. Comment out with # any uncommented send host-name lines
  3. Add the line send host-name "NewProp";
  4. CTRL-X followed by Y and Enter to save & exit nano editor.
You need to select a static IP address for the prop.  I used 10.10.1.1 for the first prop.  The next prop will use 10.10.2.1 and so on.

I was able to successfully complete this step by following the instructions in these articles:

https://frillip.com/using-your-raspberry-pi-3-as-a-wifi-access-point-with-hostapd/
  • In /etc/hostapd/hostapd.conf, "driver=nl80211", the character after the n is an L not a 1.
  • Change all occurrences of 172.24.1 to 10.10.1
  • In /etc/hostapd/hostapd.conf change "ssid=Pi3-AP" to "ssid=NewProp"
http://serverfault.com/questions/351108/using-dnsmasq-to-resolve-all-hosts-to-the-same-address
  • Change "address=/#/192.168.2.1" to "address=/#/10.10.1.1"

After all the configuration changes have been made, run sudo reboot to reboot the Pi.

On the iPad, the wifi network shows up:
 
 
After connecting this is the IP info I got:


Running Fing on the iPad shows the Pi on the network under the specified hostname:


However, for the rest of the project we need to switch the Raspberry Pi 3 back to connecting to an existing wifi network so it has internet access to install packages and we can SSH to it from another computer.  The instructions for that are at:

https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md

You can use Fing on the iPad to determine what IP address it got from your home DHCP server (router):


Then you can use an SSH client (such as Putty) from any computer on your home wifi network to connect to the Pi to continue installation and configuration.

If SSH is not enabled on the Pi run sudo raspi-config and go to Advanced Options.  You should find SSH there.

Continue to Part 2