Sunday, 19 January 2014

Installing Ubuntu on a Retina Macbook Pro - the easy way

In my previous installation guide, I outlined the first way that I found of installing Ubuntu on a Retina Macbook Pro. One of the challenges of the installation was that the boot manager, rEFInd, needed the Linux kernel to be copied from the Linux partition to the Mac OS X partition. This then becomes a painful process that needs to be repeated every time there is a kernel update on Ubuntu. Fortunately, there is a better way! Thanks to a comment on the rEFInd website, I found out that file system drivers can be installed that allow rEFInd to read the Linux partition.

This post outlines the full installation instructions, but if you already followed the previous guide, you can update the rEFInd installation and configuration file. I've included some instructions on that in the post.

1. Partition the Hard Drive

This step is nice and easy on the Mac. Just launch Disk Utility, click on the laptop's hard drive and click on the Partition tab. From there the Mac OS X partition can be resized. Disk Utility allows you to create a new partition with the extra space, but I just left it as Free Space, so that it would be created by the Ubuntu installer.

2. Create the Ubuntu USB Installer

The latest stable release of Ubuntu is available at http://www.ubuntu.com/download - you'll need the 64-bit Mac (AMD64) desktop image.

Instructions for creating a bootable USB stick are provided http://www.ubuntu.com/download/help/create-a-usb-stick-on-mac-osx, you'll just need to remember to use the latest ISO that was downloaded above. Note: unlike some disk image files, Mac OS X cannot mount the disk image, but it will boot fine from it.


3. Install an EFI Boot Manager: rEFInd

Previously, I've used Refit as a boot manager and boot loader for Ubuntu on a Mac, but that doesn't seem to be maintained any more. So, for the Retina Macbook Pro I've switched to rEFInd, which is just a Boot Manager. We'll then be loading Ubuntu using EFI instead of Grub, which means we can leave the old world of BIOS behind. See the rEFInd website for more information about boot managers and loaders, EFI and Grub.

Download the binary rEFInd zip file from http://www.rodsbooks.com/refind/getting.html and unzip it by double-clicking the file in the Mac OS X Finder. You'll want to check out the rEFInd installation instructions, but I chose the simplest option of installing rEFInd in the Mac OS X partition. There are other possibilities, but this seemed the easiest for me to manage - especially if something went wrong.

The installation needs to be done in the Terminal, by running the install.sh script:
 cd ~/Downloads/refind-bin-0.7.7  
 ./install.sh --alldrivers

The '--alldrivers' option installs the file system drivers for rEFInd, which allows the boot manager to be able to access the Ubuntu kernel files on the Linux file system. If you are upgrading from a previous installation of rEFInd, it will keep your existing rEFInd config file and copy the latest version with a different name.

The script will prompt for your password so it can run with administrator privileges using sudo. Once the script has run, rEFInd is installed and you can see the configuration files at /EFI/refind.

You'll need to reboot a couple of times before you can see the rEFInd menu appearing. We'll need to configure rEFInd later.

4. Installing Ubuntu

Connect your bootable USB drive into the Macbook Pro and reboot - you should see the USB stick as an option in the rEFInd boot menu, so boot from that. In the Ubuntu installer, select the Try Ubuntu option and it will take you to the Ubuntu desktop at a resolution of 2880x1800 - you may need a magnifying glass handy to read the text. That said, it does look beautiful!

By default, Ubuntu has 'touch to click' enabled for the trackpad by default, which I found difficult work with. So the first thing I did was to turn that off in the Mouse and Trackpad area of System Settings. Next, it's worth changing the screen resolution to something more usable - I selected 1680x1050 (16:10). After that, if you are using WiFi, then you'll need to connect to the network.


4.1 Install Ubuntu

You're now ready to install Ubuntu. We want to do this without installing the Grub boot-loader, which would put us back into the old-world BIOS mode. To install without Grub, run the following in a terminal:
 ubiquity -b  
This will launch the installer and you can follow the instructions to install Ubuntu on the free space that we created earlier, alongside Mac OS X.

Once you are done, you can reboot into Mac OS X. You'll notice that the Ubuntu partition is not showing up in rEFInd as yet - that's what we need to fix next.

5. Configure rEFInd

We need to configure rEFInd so that it sees that Ubuntu partition and has all the correct details so it can boot from it. The rEFInd configuration is in /EFI, which will need root access to be able to update the details. I found that TextWrangler is a great option for editing config file as it allows you to authenticate to update the files. Make sure that you download TextWrangler from the Barebones site as the version in the Apple App Store does not have this facility.

5.1 Configuration File Changes

It's worth checking the rEFInd site for more details about the configuration file changes, as there are a lot more options than I will cover. The main configuration file is /EFI/refind/refind.conf. If you've upgraded from a previous version of rEFInd, you may want to use the sample config file instead of the current version that you are using. We need to configure rEFInd so that it scans the hard disk for other boot options. The following file shows only the lines that I've changed from the default config file:



# Enable the scan for file system drivers
scan_driver_dirs EFI/tools/drivers,drivers

# Choose which drives to scan. This will only scan the internal hard drive.
scanfor internal

# Load the Linux file system driver
fs0: load ext4_x64.efi
fs0: map -r

These configuration file changes ensure that the Linux file system driver is loaded (ext4_x64.efi) and that the internal hard disk is scanned for bootable partitions. If there is more than one kernel found on the Linux file system, rEFInd will display all the available kernels.

That's it. If you want to make the boot screen a it prettier, you can copy a PNG or BMP image file to /EFI and add an extra line to the configuration file:
banner /EFI/MilkyWay.png 


6. Reboot Into Ubuntu

Once you reboot you should see the Ubuntu icon in the rEFInd boot menu, and it should start up. When  it does, you'll see Ubuntu in its 2880x1800 pixel glory. I've increased the default text size in Ubuntu and the browsers to roughly 1.5 times the normal size, and that has made a great work machine.


Sunday, 24 February 2013

Installing Ubuntu on Retina Macbook Pro


There is an update to this post that shows a simpler and more maintainable approach to the installation.

Installing Ubuntu on a Mac tends to be a little trickier than installing on a PC as Macs use EFI instead of BIOS. Now, with the introduction of Apple's Retina Macbook Pro screens we have an additional complication. However, Canonical and the Ubuntu community have been investing some time in getting the Retina Macbooks to play nice with Ubuntu 13.04, so I decided to get the latest, bleeding edge version. The great thing is that there has been an effort to keep the trunk version stable, so I've that getting the pre-release version of Ubuntu 13.04 to be a great solution.

If you search the Internet for information about running Ubuntu on the Retina Macbook Pro, you'll find tales of issues with the screen resolution (running at 2880x1880 with tiny icons and text), and driver issues with WiFi and sound. Well, I'm pleased to say, that Ubuntu 13.04 (with the 3.8.0-6 kernel) resolves these issues. There are some extra steps to take during the installation process, but these are related to EFI rather than Ubuntu itself. This guide is a walkthrough of the steps that I took to partition Macbook Pro hard drive and to install a dual-boot system: Mac OS X 10.8 and Ubuntu 13.04 (pre-release).

Partition the Hard Drive

This step is nice and easy on the Mac. Just launch Disk Utility, click on the laptop's hard drive and click on the Partition tab. From there the Mac OS X partition can be resized. Disk Utility allows you to create a new partition with the extra space, but I just left it as Free Space, so that it would be created by the Ubuntu installer.

Create the Ubuntu USB Installer

The latest stable release of Ubuntu is available at http://www.ubuntu.com/download, but I wanted pre-release version, which is at http://cdimage.ubuntu.com/daily-live/current/. You'll need the 64-bit Mac (AMD64) desktop image.

Instructions for creating a bootable USB stick are provided http://www.ubuntu.com/download/help/create-a-usb-stick-on-mac-osx, you'll just need to remember to use the latest ISO that was downloaded above.

Install an EFI Boot Manager: Refind

Previously, I've used Refit as a boot manager and boot loader for Ubuntu on a Mac, but that doesn't seem to be maintained any more. So, for the Retina Macbook Pro I've switched to Refind, which is just a Boot Manager. We'll then be loading Ubuntu using EFI instead of Grub, which means we can leave the old world of BIOS behind. See the Refind website for more information about boot managers and loaders, EFI and Grub.

Download the binary Refind zip file from http://www.rodsbooks.com/refind/getting.html and unzip it by double-clicking the file in the Mac OS X Finder. You'll want to check out the Refind installation instructions, but I chose the simplest option of installing Refind in the Mac OS X partition. There are other possibilities, but this seemed the easiest for me to manage - especially if something went wrong.

The installation needs to be done in the Terminal, by running the install.sh script:
 cd ~/Downloads/refind-bin-0.6.7  
 ./install.sh  

The script will prompt for your password so it can run with administrator privileges using sudo. Once the script has run, Refind is installed and you can see the configuration files at /EFI/refind.

You'll need to reboot a couple of times before you can see the Refind menu appearing. We'll need to configure Refind later.

Installing Ubuntu

The main challenge I hit during the installation process is that we need to copy the Ubuntu kernel file and RAM disk image over to the Mac OS X partition. However, though you can see the Mac OS X partition from Ubuntu, it is read-only. So, we'll need a method of copying the files over once Ubuntu has been installed.

One method is to upload the files to another server when you are booted into Ubuntu - which means that you need a network connection running. On the Retina Macbook Pro, there is no built-in Ethernet, so you're only option is to use WiFi. However, when booted off the USB stick the Macbook's WiFi does not work without extra drivers. So the option is to use an external WiFi card that does work from the installer (I used an Edimax EW-7811UN Nano Adapter), use an external USB drive, or an Apple Thunderbolt Ethernet Adapter (untested). However, given that Ubuntu 13.04 is still in development, you may find that WiFi works for you when you boot from the USB stick.

Connect your bootable USB drive into the Macbook Pro and reboot - you should see the USB stick as an option in the Refind boot menu, so boot from that. In the Ubuntu installer, select the Try Ubuntu option and it will take you to the Ubuntu desktop at a resolution of 2880x1800 - you may need a magnifying glass handy to read the text. That said, it does look beautiful!

By default, Ubuntu has 'touch to click' enabled for the trackpad by default, which I found difficult work with. So the first thing I did was to turn that off in the Mouse and Trackpad area of System Settings. Next, it's work changing the screen resolution to something more usable - I selected 1680x1050 (16:10). After that, if you are using WiFi, then you'll need to connect to the network.

Install Ubuntu

You're now ready to install Ubuntu. We want to do this without installing the Grub boot-loader, which would put us back into the old-world BIOS mode. To install without Grub, run the following in a terminal:
 ubiquity -b  
This will launch the installer and you can follow the instructions to install Ubuntu on the free space that we created earlier, alongside Mac OS X. At the end of the installation, make sure that you choose the option to Continue to try Ubuntu, as there is some more work to do here.

Copy the Kernel and RAM Disk Image Files

The next step is to copy the kernel file and the RAM disk image to your external server or flash drive. The files that you need are in /boot and will be called something like vmlinuz-3.8.0-6-generic and initrd.img-3.8.0-6-generic. If you have your Internet connection working, the simplest option is to upload the files to Ubuntu One, DropBox or Google Drive.

Make a Note of the UUID

You'll need to know the UUID of the partition that you have just installed Ubuntu on. You can see this in the Nautilus File Manager window when you select the Ubuntu partition (in the title bar). Or, you can see it by running:
 sudo blkid /dev/sda5  

You'll need to replace sda5 with the partition that you used. The UUID will be a long list of characters like 27c9a93d-6cc8-2395-9a97-d105353e5c07 - we'll need this for the Refind configuration file.

Once you are done, you can reboot into Mac OS X. You'll notice that the Ubuntu partition is not showing up in Refind as yet - that's what we need to fix next.

Configure Refind

We need to configure Refind so that it sees that Ubuntu partition and has all the correct details so it can boot from it. The Refind configuration is in /EFI, which will need root access to be able to update the details. I found that TextWrangler is a great option for editing config file as it allows you to authenticate to update the files. Make sure that you download TextWrangler from the Barebones site as the version in the Apple App Store does not have this facility.

Copy the Kernel and RAM Disk Image Files

The first step is to create a new folder in the EFI config area that will hold the Ubuntu kernel and disk image: /EFI/ubuntu. You'll need to copy the Ubuntu kernel and RAM disk image files into the new folder from the server or flash drive that you used earlier.

Configuration File Changes

It's worth checking the Refind site for more details about the configuration file changes, as there are a lot more options than I will cover. The main configuration file is /EFI/refind/refind.conf. We need to set up a configuration section for Ubuntu, so edit the file and add the following section:
1:  menuentry Linux {  
2:       icon EFI/refind/icons/os_ubuntu.icns  
3:       volume 5:  
4:       loader EFI/ubuntu/vmlinuz-3.8.0-6-generic  
5:       initrd EFI/ubuntu/initrd.img-3.8.0-6-generic  
6:       options "ro root=UUID=27c9a93d-6cc8-2395-9a97-d105353e5c07"  
7:       #disabled  
8:  }  
Note that there is a menuentry Linux section already in the file, and I have just edited that section. Some of the key points to note:

  • Line 2: the icon that will be displayed on the boot manager screen. In this case, I'm using the Ubuntu logo instead of Tux.
  • Line 3: you can find the volume by running diskutil list.
  • Lines 4-5: the paths to the kernel and RAM disk image.
  • Line 6: the UUID of the Ubuntu partition that you made a note of earlier.
  • Line 7: make sure that you comment out or remove the disabled line, otherwise it will not show up in the boot menu.
That's it. If you want to make the boot screen a it prettier, you can copy a PNG or BMP image file to /EFI and add an extra line to the configuration file:
banner /EFI/MilkyWay.png 

Reboot Into Ubuntu

Once you reboot you should see the Ubuntu icon in the Refind boot menu, and it should start up. When  it does, you'll see Ubuntu in its 2880x1800 pixel glory. So once you changed the resolution to a reasonable setting, you should find Ubuntu running beautifully:

  • The WiFi adapter works out of the box.
  • The sound card works.
  • The web cam works.

In fact, I've been using Ubuntu on the Retina Macbook Pro as my main work machine for a week now and I've not found anything that does not work.

Thursday, 31 January 2013

Web-based IR Remote on the Raspberry Pi

There are many devices that use infrared remote controls - TV's, DVD players, cameras, power sockets. So getting a Raspberry Pi to be able to send remote control signals opens up many possibilities for projects. Combining the GPIO pins with a web server on the Raspberry Pi means that we can create a web UI to control these devices.

Installing LIRC on the Raspberry Pi

One of the great things about running a Linux operating system on the Raspberry Pi is that it provides access to a wealth of software projects that can run on the device. One of these is the Linux Infrared Remote Control (LIRC) project that provides a way of receiving and transmitting IR signals from many remote controls. LIRC provides a method of recording signals from a remote control and storing them in a configuration file, so that they can be sent directly from the Raspberry Pi.

Installing LIRC on the Raspberry Pi needs the latest firmware to be on the Raspberry Pi. One of the clearest guides I've found on the process of updating your firmware and installing LIRC is on Alex Bain's site. That walks you through the process of installing LIRC and getting the initial configuration done.

IR Receiver and Transceiver Circuits

Once LIRC is set up, we need to set up an infrared receiver and transmitter circuit.

IR Receiver

The receiver circuit is the simplest to set up. I've used a TSOP382, but check the data sheet for your IR receiver as the pins for ground and Vcc are sometimes the other way round. If you connect those pins incorrectly you could fry the IR receiver. Also, note that I'm connecting the Vcc pin to 3.3V as the TSOP382 works fine on that voltage.

The Adafruit site has a great walkthrough of testing and using an IR receiver.

IR Transmitter

The IR transmitter circuit is a bit more complex as the current output from the Raspberry Pi GPIO pins will only give you a very weak signal from the IR transmitter LED. If you search on the Internet you'll find a number of different circuits that you can use to amplify the signal so that you can get a few meters distance of signal from your IR LED.

I'm sure sure what the IR LED I've used as I rescued it from a Sony DVD remote control. In terms of the components to use for the circuit, you'll find a number of options. I used the components that I had available (Q1=BC547 transistor, R1=220ohm, R2=omitted as I didn't have a low enough resistor). Though I haven't measured the range of the signal, it works fine from 4m away from the devices.


Web-Controlled Remote

Once LIRC is setup and you can configured at least one remote, sending commands to through the IR LED is as simple as:
 #                device command  
 irsend SEND_ONCE Humax  KEY_POWER  

Of course, we don't want limit people to controlling the TV by ssh-ing into the Raspberry Pi to change the channel. So we need a web-based UI that people can access through a computer, tablet or smart phone. I got my 11-year old son to work on a design using Inkscape so that I'd have an SVG image that I could use as the web interface on an HTML5 web page. After a few iterations on the design, we came up with this:

The advantage of using an SVG file is that it will scale naturally with the device that it is viewed one, so should work well on a smartphone's 4-inch screen as well as on a 20-inch monitor.

Flask Web Application

The web application has been written using the Flask micro-framework, similar to my previous post. This time, the application reads the LIRC config file (/etc/lirc/lircd.conf) and gets the names of the devices that have been configured, and presents them to the user.
The web page uses JQuery Mobile to make it look good on smaller devices. Once the user selects the relevant device, the remote control is shown and the user can press a button on the touchscreen to operate the remote. Each button is configured to send a different operation e.g. pressing V+ will send KEY_VOLUMEUP. As we've seen previously, LIRC's irsend command only needs the device name and the operation command code to send the signal to the LED. With Flask, this can be done in less than 50 lines of code:
 #!/usr/bin/env python  
   
 from lirc.lirc import Lirc  
 from flask import Flask  
 from flask import render_template  
 from flask import request, redirect, url_for  
   
 BASE_URL = ''  
   
 app = Flask(__name__)  
   
 # Initialise the Lirc config parser  
 lircParse = Lirc('/etc/lirc/lircd.conf')  
   
   
 @app.route("/")  
 @app.route("/<device>")  
 def index(device=None):  
   # Get the devices from the config file  
   devices = []  
   for dev in lircParse.devices():  
     d = {  
       'id': dev,  
       'name': dev,  
     }  
     devices.append(d)  
     
   return render_template('remote.html', devices=devices)  
   
 @app.route("/device/<device_id>")  
 def device(device_id=None):  
   d = {'id':device_id}      
   return render_template('control.html', d=d)  
   
   
 @app.route("/device/<device_id>/clicked/<op>")  
 def clicked(device_id=None, op=None):  
   # Send message to Lirc to control the IR  
   lircParse.send_once(device_id, op)  
     
   return ""  
   
   
 if __name__ == "__main__":  
   app.debug = True  
   app.run('0.0.0.0')  
   

The only complexity that we come across of parsing the LIRC config file to get the names of the devices. Unfortunately, they have not used a standard format like YAML for their config file, so the parser may run into problems if you add comments on the same line as your commands. However, sending the command to LIRC is straightforward using a shell command to irsend:
 from subprocess import call  
   
 ...  
   
 def send_once(self, device_id, message):  
      """  
      Send single call to IR LED.  
      """  
      call(['irsend', 'SEND_ONCE', device_id, message])  
   

The full code is available on GitHub: https://github.com/slimjim777/web-irsend.


Tuesday, 22 January 2013

Controlling the RaspberryPi from a Web Application

The AdaFruit website has an excellent tutorial on connecting a 16x2 LCD display to a Raspberry Pi. That's great, but what if you want to be able to send messages to the display from a web application? In the previous tutorial, we saw how to create a basic Python-based web application using the Flask framework. Let's create a new web application that will interact with the Raspberry Pi.


The Goal

Using Flask, we will create a simple web application with with a form that allow a user to send a message to the Raspberry Pi using a web browser. This will allow us to control the Raspberry Pi from a PC, tablet or smart phone. When the form is submitted, it will send the message to the LCD via the device's GPIO ports. All the code, including the web application, is in Python and HTML... with some HTML and JQuery Mobile thrown in (just because we can).

To the Code

We'll be using the same circuit and the AdaFruit_CharLCD.py library, so make sure you have everything up-and-running as per the AdaFruit tutorial. So let's set up the folder structure that we'll need:
 /lcd  
    lcd.py  
    /adafruit  
        __init__.py
        Adafruit_CharLCD.py  
    /templates  
        index.html  
    

The source for application is available at https://github.com/slimjim777/web-lcd. The application uses the Adafruit class to communicate with the LCD from the Raspberry Pi. The only changes to the code were to convert tabs to spaces in the class (Python is generally very fussy over combining tabs and spaces for indentation).

Main LCD Application

The main LCD application is lcd.py, which is the app controller for the Flask framework.

 from flask import Flask  
 from flask import render_template, request  
 from adafruit.Adafruit_CharLCD import Adafruit_CharLCD  
   
 app = Flask(__name__)  
   
 # Initialise the LCD class  
 lcd = Adafruit_CharLCD()  
 lcd.begin(16,2)  
   
   
 @app.route("/")  
 def index():  
   return render_template('index.html', value=value)  
 
 ...

The script initializes the Adafruit LCD class and sets the size of the display (16x2 characters). After that the Flask index method is defined that renders the Jinja2 template. The template contains the web form to allow users to submit messages to the LCD:
 {% extends "base.html" %}  
 {% block body %}  
 <div data-role="header">  
  <h1>Raspberry Pi Controller</h1>  
 </div>  
   
 <div data-role="content">  
   
 <form method="post" action="change">  
  <label for="slider-1">Message to Send:</label>  
  <input type="text" name="lcd" id="lcd" />   
  <br />  
    
  <input type="submit" value="Submit" />  
 </form>  
   
 {% if value %}  
 <p>Message sent: {{ value }}</p>  
 {% endif %}  
   
 </div>  
 {% endblock %}  
   

The Jinja2 template extends from the base.html template, which contains the main details of the HTML page, including importing the JQuery Mobile libraries and CSS (to style the web page for mobile devices).

Starting the Web App

To start the web application, run:
 sudo python lcd.py  
   
This needs to be run with elevated permissions (using sudo) as it is communicating to the GPIO ports. Now, browsing to port 5000 on the Raspberry Pi will bring up the web form.


When the form is submitted, it send an HTTP POST request to the change method, including the message text that has been submitted.

 @app.route("/change", methods=['POST'])  
 def change():  
   if request.method == 'POST':  
     # Get the value from the submitted form  
     lcdText = request.form['lcd']  
     print "---Message is", lcdText  
       
     # Send the message to the LCD  
     lcd.clear()  
     lcd.message(lcdText)  
   else:  
     lcdText = None  
   return render_template('index.html', value=lcdText)  
   

The change method retrieves the message text from the HTTP POST request and stores it in the lcdText variable. Now, and this is the really clear bit, because all this code is running on the Raspberry Pi, that text can be sent through the device's GPIO port to the LCD using the Adafruit_CharLCD class. That's the beauty and simplicity of using a Python-based web-framework - the same code that someone else has developed to drive the LCD can be used directly in the web application.

This is a fairly simple example without much of a real-world use. But a similar approach could be taken to drive any component or device that is connected to the Raspberry Pi. That could be to switch a relay to turn on the central heating in your home automation system, or to send an message to an IR LED that will change the channel on the TV.

Monday, 21 January 2013

Python Web Application Server on the RaspberryPi


One of the great features of the Rev. B RaspberryPi is the built-in Ethernet connection, which opens up many possibilities for web-connected projects. This enables this small device to be able to operate as a web server, ideal for running custom web applications. Since the RaspberryPi can also be connected to a host of other sensors and devices through the GPIO ports, this opens up the possibility of creating web-controlled devices.

Choosing a Web Framework

Since Python is the main programming language for controlling the RaspberryPi, I thought that the ideal web server for the device is a Python-based web framework. This means that the code for controlling the RaspberryPi's GPIO could be integrated right into the code for the web server.

There are a number of Python web frameworks available - so that run some heavy-weight Internet websites. However, the ideal solution is a web framework that is:
  • Easy to install
  • Quick to learn
  • Simple to write
  • Fast and lightweight
Even when considering this criteria, there are multiple options. I settled on one that I really like: Flask. The Flask project describes the framework as a microframework that is fun to work with. That sounds like the perfect accompaniment to a RaspberryPi!

Installing Flask on the RaspberryPi

Installing Flask on the RaspberryPi is really straightforward:

 sudo apt-get install python-pip  
 sudo pip install Flask  
 That's it! What we get is a built-in web server, a Python web framework which is WSGI-compliant, and a built-in templating engine (Jinja2 templates).

Hello World Web App

Once you have Flask installed, then you'll be itching to write your first "Hello World!" web app. Just find a suitable location on your RaspberryPi to store your code (I like to use a 'Sites' directory in the home folder and create a sub-directory for each project e.g. ~/Sites/hello), and a hello.py file as follows:

 from flask import Flask  
 app = Flask(__name__)  
 @app.route("/")  
 def hello():  
   return "Hello World!"  
 if __name__ == "__main__":  
   app.run('0.0.0.0')  

If you've checked out the Flask website, you'll recognise this code as their starting example, with one difference: the addition of '0.0.0.0'. This makes sure that the web server is going to listen on all network devices, so you can browse to the web site from anywhere on your local network.

To start the web server just run:
 $ python hello.py   
  * Running on http://0.0.0.0:5000/  

This will start the built-in web server and it will be listening for web requests on port 5000. You can browse to your web site from any computer, tablet or smart phone that is on your local network by navigating to http://the-ip-address-of-your-pi:5000/ e.g. http://192.168.1.105:5000/. There you will be greeted by your glorious, welcoming message.

Adding a Templated Web Page

Generating HTML from Python code quickly becomes unmanageable, so the recommended approach is to use a templating engine. The Flask install includes the Jinja2 templating engine which makes it quick and easy to develop web applications. Flask is configured to look for templates in a directory called templates. So create a folder structure like this:

 /hello  
   hello.py  
   /templates  
     hello.html  


So, let's create the hello.html template:
 <!DOCTYPE HTML>  
 <html>  
 <header>  
   <title>Welcome!</title>  
 </header>  
 <body>  
   <h1>Hello from the RaspberryPi</h1>  
 </body>  
 </html>  

And now change hello.py to use the template. This is done using render_template:
 from flask import Flask  
 from flask import render_template  
   
 app = Flask(__name__)  
   
 @app.route('/')  
 def hello(name=None):  
   return render_template('hello.html')  
     
 if __name__ == "__main__":  
   app.run('0.0.0.0')  

Restart the web server by running python hello.py and visit the RaspberryPi web page to see your new templated, web application.

That's it! You now have the basis for developing web applications that run on the RaspberryPi, written in Python. For more information on Flask, I recommend working through the tutorials on the Flask website. Once you have a better grasp of working with Flask, you'll be ready to add Python code that controls your RaspberryPi directly from your web application. Stay tuned for the next lesson.