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!

No comments:

Post a Comment