From 1daf61570c5d93104bc60ed85b3c00c36da3286a Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 31 Jul 2019 19:00:35 +0100 Subject: [PATCH] pruned old labs --- 01 Getting Started.md | 133 +++++ 01 Lab 1 Introduction to Arduino.md | 286 --------- 01 Teambuilding.md | 71 --- 02 Lab 1 Test-Driven Development.md | 101 ---- 02 MQTT CLI.md | 79 --- 02 MQTT JavaScript.md | 202 ------- 02 MQTT Raspberry Pi.md | 541 ------------------ 02 Using the I2C Protocol.md | 148 +++++ 03 Creating an MQTT Broker.md | 312 ++++++++++ 03 Version Control.md | 80 --- ... W.md => 04 Building a Bluetooth Beacon.sh | 0 04 Team Psychology.md | 53 -- 05 Scrum.md | 98 ---- 06 Communication.md | 61 -- 07 Kanban Boards.md | 96 ---- 08 Effective GitHub.md | 2 - 09 Burndown Charts.md | 57 -- 10 Co-Working.md | 51 -- README.md | 56 +- exercises/.images/etcher_software.png | Bin 0 -> 94724 bytes exercises/.images/raspbian_buster.png | Bin 0 -> 39137 bytes exercises/.images/raspi-config_tool.png | Bin 0 -> 44472 bytes projects.md | 12 - 23 files changed, 595 insertions(+), 1844 deletions(-) create mode 100644 01 Getting Started.md delete mode 100644 01 Lab 1 Introduction to Arduino.md delete mode 100644 01 Teambuilding.md delete mode 100644 02 Lab 1 Test-Driven Development.md delete mode 100644 02 MQTT CLI.md delete mode 100644 02 MQTT JavaScript.md delete mode 100644 02 MQTT Raspberry Pi.md create mode 100644 02 Using the I2C Protocol.md create mode 100644 03 Creating an MQTT Broker.md delete mode 100644 03 Version Control.md rename 02 Raspberry Pi Zero W.md => 04 Building a Bluetooth Beacon.sh (100%) delete mode 100644 04 Team Psychology.md delete mode 100644 05 Scrum.md delete mode 100644 06 Communication.md delete mode 100644 07 Kanban Boards.md delete mode 100644 08 Effective GitHub.md delete mode 100644 09 Burndown Charts.md delete mode 100644 10 Co-Working.md create mode 100644 exercises/.images/etcher_software.png create mode 100644 exercises/.images/raspbian_buster.png create mode 100644 exercises/.images/raspi-config_tool.png delete mode 100644 projects.md diff --git a/01 Getting Started.md b/01 Getting Started.md new file mode 100644 index 0000000..0434d24 --- /dev/null +++ b/01 Getting Started.md @@ -0,0 +1,133 @@ + +# Setting up the Raspberry Pi + +In this worksheet you will be shown how to setup and configure a raspberry pi as a central 'hub' for your home automation system. By the end of this you will have: + +1. The operating system (Debian Stretch Lite) installed on the hub. +2. The I2C interface configured for use (and a small display attached). +3. A working MQTT broker installed (but not fully secured!). +4. The latest versions of Python and Pip. +5. A NodeJS runtime environment for running scripts. We will then use this to publish a simple API. + +## 1 Installing the Operating System + +In this worksheet we will be using the [Raspbian Buster Lite distro](https://www.raspberrypi.org/downloads/raspbian/) which is a very cut down version of the [Debian Server](https://www.debian.org/distrib/). To complete this step you will need an SD card of at least 8GB since the operating system takes up 4GB and you will need to leave room for your scripts and applications. + +![Link to download Raspbian Buster Lite](exercises/.images/raspbian_buster.png) + +Make sure you download the _lite_ version which should be an `.img` file of around 426MB. If your download is over 1GB you have downloaded the wrong file! + +The download will be an `.img` file and needs to be burned onto the SD card. There are several different ways to do this but we recommend you use the [Balena Etcher](https://www.balena.io/etcher/) application. + +![The Balena Etcher Software](exercises/.images/etcher_software.png) + +### 2 Configuring the Image Pre-Boot + +Before we boot for the first time there are a number of settins that need to be changed. These changes are made by pluggin in the SD card into your computer and looking for an external drive called `boot`. If you open this you will see a number of config files. It is here that we will need to make our changes. + +The first is to allow us to connect remotely into the Raspberry Pi using SSH. By default this is disabled (for security reasons). Create a new text file in the `boot` partition and call it `ssh`. Make sure your computer has not added a file extension. This file should be left empty. + +The second change is to enable the on-board WiFi and connect it to a suitable network. If you are only going to be using the Raspberry Pi at home you can connect to your home WiFi router however if you are planning to use it in different places it would be better to connect to your smartphone hotspot as it is difficult to change the settings and we won't be downloading large files. + +Create a new text file called `wpa_supplicant.conf` and insert the following, making sure to substitute your WiFi SSID and password. Note that you won't be able to connect to the University Cisco networks requiring a username and password. + +``` +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev +network={ + ssid="YOUR_SSID" + psk="YOUR_WIFI_PASSWORD" + key_mgmt=WPA-PSK +} +``` + +## 3 First Boot + +Now you can eject the MicroSD card, insert it into your Raspberry Pi and power it up. Note that for this initial boot you will need to have a keyboard and monitor connected. Once you have completed this section you will be able to connect remotely and can run the raspberry Pi headless. Take care inserting the power supply as the USB socket on the board can be quite delicate. + +The username is `pi` with a default password of `raspberry`. + +### 3.1 Updating the Software + +The first task we should do is to update the software installed on the Raspberry Pi and install some additional packages. This is done using the `apt` tool. + +```shell +sudo apt update +sudo apt upgrade -y +sudo apt install -y apt-transport-https rsync sudo nano git tree curl software-properties-common mc build-essential libssl-dev libffi-dev i2c-tools +``` + +### 3.2 Changing the Default Password + +When you logged in using the `pi` user you used a default password which will be the same for all installations unless it is changed. For the sake of security we should change this as soon as possible using the `passwd` command. If you run this you will be prompted for the current password then asked to type in your new password twice to ensure you have not miss-typed. Don't forget this new password! Note that when you enter any password text nothing shows on the screen! + +```shell +$ passwd + Changing password for pi. + Current password: + New password: + Retype new password: + passwd: password updated successfully +``` + +### 3.3 Find the IP Address + +it is a good idea to make a note of the current IP address of your Raspberry Pi. You can do this by running the `ifconfig` command and looking under the `wlan0` section of the report for the `inet` label. In the example below the device ip address is `192.168.0.59`: + +```shell +wlan0: flags=4163 mtu 1500 + inet 192.168.0.59 netmask 255.255.255.0 broadcast 192.168.0.255 + inet6 2a02:c7d:768d:9900:a9f6:6bd9:3c31:8b5f prefixlen 64 scopeid 0x0 +``` + +Make a careful note of this IP address, you may need it in the next section! + +### 3.3 Changing the Host Name + +Every device on the network is configured with a _host name_. If you run the `hostname` command you can see that this defaults to `minibian`. Since every raspberry pi running the Minibian distro could have the same name this is not very satisfactory! + +To change the hostname you need to run the `sudo raspi-config` command. This will display a menu containing a number of configuration choices (see below). + +![Raspi Config Menu](exercises/.images/raspi-config_tool.png) + +You should choose menu option 2 using the down arrow and enter key. On the second screen choose the `Hostname` option (first in the list). Read the information on the next screen and press enter to continue where you will be asked to choose a new name. To ensure you have a unique name use your University username entered as lowercase letters and digits. When done press enter to return to the main menu. Press the right arrow to exit. + +You will be asked to reboot, opt for the not now option as we need to fully power down the Raspberry Pi. + +Once you are back at the prompt do a controlled shutdown using the `sudo shutdown now` command. This will power down the computer in a controlled manner. + +## 4 Connecting using Secure Shell + +Up to this point we have connected a monitor and keyboard to our server and used this to interact with the system. Most servers run _headless_ and we connect remotely using secure shell (ssh). To do this we need to know the _hostname_ or the _ip address_ of the system. + +Start by disconnecting the power cable, screen and keyboard and then re-insert the power cable, this will boot up the Raspberry Pi in _headless mode_. You should then pick from either section 4.1 if you want to connect using a MacOS or Linux computer or section 4.2 if you are stuck with Windows 10. + +### 4.1 Logging in Using SSH using MacOS or Linux + +If you are using a Mac or Linux laptop you connect using the ssh command through the terminal, replacing `doej` with the username you used as your hostname. + +You will be prompted for your password and, the first time you connect, the server will attempt to send you its public encryption key, you will be asked if you want to accept this. + +``` +$ ssh pi@doej + The authenticity of host 'aa7401 (192.168.0.59)' can't be established. + ECDSA key fingerprint is SHA256:Yy1dIb646N+j98oJoa+I5Omt7eGfXp7HdLzihUVaEC8. + Are you sure you want to continue connecting (yes/no)? + Warning: Permanently added 'aa7401' (ECDSA) to the list of known hosts. + pi@doej's password: + Linux aa7401 4.19.58-v7+ #1245 SMP Fri Jul 12 17:25:51 BST 2019 armv7l + + The programs included with the Debian GNU/Linux system are free software; + the exact distribution terms for each program are described in the + individual files in /usr/share/doc/*/copyright. + + Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent + permitted by applicable law. + Last login: Wed Jul 31 17:56:05 2019 from 192.168.0.54 +pi@doej:~ $ +``` + +### 4.2 Logging in using Windows 10 + +If you are using Windows 10 you will need to download the [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) application. After launch you need to enter the hostname and user credentials in the appropriate boxes. Once logged in, Putty behaves like a standard terminal window. + +If the credentials are correct you are now connected to the server and all the commands you enter will be run on it. To quit and return to your computer enter the `exit` command. diff --git a/01 Lab 1 Introduction to Arduino.md b/01 Lab 1 Introduction to Arduino.md deleted file mode 100644 index 0f32ff9..0000000 --- a/01 Lab 1 Introduction to Arduino.md +++ /dev/null @@ -1,286 +0,0 @@ - -# Introduction to Arduino - -In this first lab you are being given time to get to grips with the Arduino platform. Rather than using the standard Arduino IDE you will be using the PlatformIO tools which integrate into Visual Studio Code. - -## 1 Installation - -_Note: If you are using the University workstations this will already have been completed._ - -You should start by installing [Visual Studio Code](https://code.visualstudio.com/) and then, using the **extensions** tab, search for and install the [PlatformIO IDE](https://platformio.org/platformio-ide). This will install the visual plugin. - -This will also install the CLI tools `platformio` and `pio`, you should locate these on your computer and add the path to your environemnt variable. There are instructions on the [Platform.io](https://docs.platformio.org/en/latest/installation.html#install-shell-commands) website with more detail below. - -### 1.1 Ubuntu 18.4 - -Edit the `~/.profile` file and add the following to the end: - -```shell -if [ -d "$HOME/.platformio/penv/bin" ] ; then - PATH="$HOME/.platformio/penv/bin:$PATH" -fi -``` - -This checks to see if platformio has created the correct directory and, if it has, the directory gets added to the `$PATH`. Note: you will need to restart your computer for this to take effect. - -Once you have done this, restart the computer and use the `ECHO $PATH` command to check that this path has been added. If it has you will be able to run the `platformio` command. - -You will also need to install the udev rules: - -```shell -$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules -``` - -### 1.2 MacOS Mojave - -Create a `~/.profile` file and add the following to the end: - -```shell -PATH="$HOME/.platformio/penv/bin:$PATH" -``` - -Once you have done this, restart the computer and use the `ECHO $PATH` command to check that this path has been added. If it has you will be able to run the `platformio` command. - -You will need to install the correct drivers. The `CH34x_Install_V1.4.pkg` can be found in the `exercises/macos_drivers/` directory. If you are using a board with a different chipset you will find the drivers in the appropriately-labelled sub-directory. - -### 1.3 Windows 10 - -If you are using Windows you will also need to install the [2102 Drivers](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers) if you are using - -Adding new paths in Windows is a lot more complicated. Follow [these instructions](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/) to add the path - -## 1 Compiling and Uploading - -All the code used by this lab can be found in the `exercises/01_arduino/` directory. As you work through these tasks, load the appropriate directory directly into VS Code. - -In this first exercise you will learn about the structure of a PlatformIO Arduino project and how to compile a program to a binary file and upload this to a microcontroller. - -In this lab you will be focussing on the commandline however there are a number of icons in the blue status bar that act as shortcuts to many of these commands. You should take time to get familiar with these. - -Use the file menu in VS Code to open the `blink/` directory then open the integrated terminal, it should point to the current project directory. - -### 1.1 Understanding the Code - -You should now use the IDE to open the `exercises/02_tdd/nodemcu/` directory which contains a simple Arduino sketch with a library. Lets look at the files: - -``` -├── platformio.ini -├── readme.md -└── src -    └── main.cpp -``` - -1. The `platformio.ini` file is the project configuration. It defines two _environment definitions_: - 1. The `nodemcuv2` environment supports the NodeMCU boards based on the ESP8266 microcontroller. - 2. The `lolin32` environment supports the Lolin32 boards based on the ESP32 microcontroller. - 2. The `native` definition allows us to develop and test our library using the native compiler on our workstation. -2. The `readme.txt` file contains the documentation. -3. The `src/` directory contains the main Arduino sketch. Notice that this imports: - 1. The Arduino libraries. - 2. Our `avg` library. -``` - -We can compile the code for a specified environment using either the `platformio` or `pio` command. The chosen environment is indicated either using the _long flag_ `--environment` or the _short flag_ `-e`. All of the commands listed below are equivalent: - -```shell -$ platformio run --environment nodemcuv2 -$ pio run --environment nodemcuv2 -$ platformio run -e nodemcuv2 -$ pio run -e nodemcuv2 -``` - -This will compile the code, checking for dependencies but _won't_ upload to the board. You should use this to check for syntax and dependency errors. - -To upload to the board you need to include the `--target` or `-t` flag. This will compile the code and attempt to upload it to the attached board. The first example uses long flags whilst the second uses the short versions: - -```shell -$ platformio run --environment nodemcuv2 --target upload -$ pio run -e nodemcuv2 -t upload -``` - -If you get an error uploading to the board it will either be due to not finding the serial port or board or it may be because of an error transferring the data. - -To see a list of all the available ports and the drivers installed, use the following command: - -```shell -$ platformio device list - /dev/ttyUSB0 - ------------ - Hardware ID: USB VID:PID=10C4:EA60 SER=0001 LOCATION=2-2.2 - Description: CP2102 USB to UART Bridge Controller -``` - -In the sample output above you can see that PlatformIO has detected a device called `/dev/ttyUSB0` which has been created by the drivers we installed earlier. Once you know the name of the port it can be added to the `platformio.ini` file (this option is currently commented out). - -If there is a data transfer error you can edit the `platformio.ini` file and reduce the upload speed. There is a comment in the sample file that lists the speeds permitted. Start with the lowest (9,600 baud). If this works you can try faster speeds. - -Once the binary has uploaded to the microcontroller it will start to execute. The code in the `main.cpp` file does two things: - -1. It blinks the built-in LED on and off once every 2 seconds. -2. It generates a random integer between 10 and 20 and sends it through the serial port back to the computer. - -There is a serial monitor that can be attached to the USB port and used to display any data being sent from the microcontroller to the computer. To open this use the following command: - -```shell -$ pio device monitor -``` - -### 1.2 Test Your Understanding - -1. Create a dice simulator that displays the results of two dice being thrown. Send this to the serial monitor. - -## 2 Using Third-Party Libraries - -In this section you will learn how to import third-party libraries. You will be displaying data on the built-in screen on the ESP32 microcontroller. We will be using the code in the `screen/` directory. Open this in VS Code. - -![LOLIN ESP32](exercises/.images/components/LOLIN.png) - -The screen is an SSD1306 and we need to search for a suitable library. The PlatformIO CLI has a [fully documented](http://docs.platformio.org/en/latest/userguide/lib/index.html) `lib` subcommand, lets try running this: - -```shell -$ platformio lib - Commands: - builtin List built-in libraries - install Install library - list List installed libraries - register Register a new library - search Search for a library - show Show detailed info about a library - stats Library Registry Statistics - uninstall Uninstall libraries - update Update installed libraries -``` - -As you can see we need to provide an additional command. Looking at the list, `search` looks like a good option. Use the [documentation](http://docs.platformio.org/en/latest/userguide/lib/index.html) to understand how the [search](http://docs.platformio.org/en/latest/userguide/lib/cmd_search.html) command works, try the following: - -```shell -$ platformio lib search --framework arduino --platform espressif32 SSD1306 -$ pio lib search -f arduino -p espressif32 SSD1306 -$ pio lib search -f arduino -p espressif32 -n SSD1306 -$ pio lib search -f arduino -p espressif32 --json-output SSD1306 -``` - -Lets look at the documentation for a library: - -```shell -$ pio lib show 562 -$ pio lib show ssd1306 -``` - -This displays the detailed documentation for the library. If there are more than one library matching the name you will be presented with a summary of each and prompted to enter the ID for the one you mean, enter `1904` and press enter. The most useful part of this is a list of links to some examples which show how you can import and use the library. Take a look at some of these to get an idea of how they work. - -To use a library you need to list it in the `platformio.ini` file. If you open this you can see we have already listed the library we want to use. - -The final step is to build (to check the dependencies and code) then upload to the Microcontroller. Notice that PlatformIO automatically installs all the libraries listed in the `platformio.ini` file. - -```shell -$ pio run -e lolin32 -$ pio run -e lolin32 -t upload -``` - -## 2.1 Test Your Understanding - -1. Send the data (milliseconds since bootup) to the serial monitor. -2. Calculate the number of _seconds_ and send to the serial monitor. -3. Display the number of seconds on the screen, under the milliseconds. -4. Display random percentages on a third line (don't forget the % symbol). -5. Make the font a lot larger! You may need to changed the text on screen to include all the data. - -## 3 Publishing Real Data - -Now we will connect a DHT11 sensor and publish the temperature data to both the screen and the serial monitor. Before we connect anything we need to understand the different pins on the mocrocontroller. - -![LOLIN PINOUT](exercises/.images/LOLIN_OLED_PINOUT.jpg) - -Now its time to wire up a _real_ sensor. In addition to the NodeMCU you will need a solderless breadboard and a DHT11 sensor as well as some jumper wires to connect everything together. The data pin should be connected to GPIO2 (pin 2) on the ESP32 microcontroller. - -If you are using the ESP8266 you should connect your wires like this (use pin D4) and modify `main.cpp` where indicated: - -![DHT11 Breadboard Wiring](exercises/.images/DHT11_breadboard.png) - -Notice that although the sensor has 4 pins we only need 3 of them. - -1. VCC/+ (connects to the 3.3v power rail) -2. DATA/OUT (connects to pin 15/D4) -3. NC (not connected) -4. GND/- (connects to the ground rail) - -If your sensor is mounted on a breakout board it will only have 3 pins and these will be clearly labelled. - -### 3.1 Test Your Understanding - -The current program simply reads an analog value from the sensor however this contains information on both temperature and humidity. To access each individual reading you will need to use a dedicated DHT11 library. - -1. Search for a suitable library for the DHT11 and add it to the `platformio.ini` file. -2. Use the knowledge from this lab to build a program to capture both temperature and humidity. -3. Send this data (together with the correct units) to the serial monitor. - -## 4 Creating a New Project - -Up to this point the overall project structure has been provided for you but how was this done? PlatformIO provides the `init` subcommand that creates the required directory structure and builds a basic ini file. - -The command requires you to pass it the **board identifier ID**. This can be found using the [Boards Catalog](http://docs.platformio.org/en/latest/boards/index.html#boards), the [Boards Explorer](https://platformio.org/boards) or by running the `boards` subcommand. Run the following command to find a board ID for the nodemcu: - -```shell -$ platformio boards nodemcu - Platform: espressif32 - ----------------------------------------------------------------------------- - ID MCU Frequency Flash RAM Name - ----------------------------------------------------------------------------- - nodemcu-32s ESP32 240MHz 4MB 320KB NodeMCU-32S - - Platform: espressif8266 - ----------------------------------------------------------------------------- - ID MCU Frequency Flash RAM Name - ----------------------------------------------------------------------------- - nodemcu ESP8266 80MHz 4MB 80KB NodeMCU 0.9 (ESP-12 Module) - nodemcuv2 ESP8266 80MHz 4MB 80KB NodeMCU 1.0 (ESP-12E Module) -``` - -From this we can see that the platform for our ESP8266 is `expressiv8266` and the ID is either `nodemcu` or `nodemcuv2`, we have the latest version (v2). - -Lets repeat this for the more powerful ESP32-based board. This board is labelled `wemos`. Searching for this returns: - -```shell -$ platformio boards wemos - Platform: espressif32 - -------------------------------------------------------------------------------- - ID MCU Frequency Flash RAM Name - -------------------------------------------------------------------------------- - lolin_d32 ESP32 240MHz 4MB 320KB WEMOS LOLIN D32 - lolin_d32_pro ESP32 240MHz 4MB 320KB WEMOS LOLIN D32 PRO - lolin32 ESP32 240MHz 4MB 320KB WEMOS LOLIN32 - wemosbat ESP32 240MHz 4MB 320KB WeMos WiFi & Bluetooth Battery - - Platform: espressif8266 - -------------------------------------------------------------------------------- - ID MCU Frequency Flash RAM Name - -------------------------------------------------------------------------------- - d1 ESP8266 80MHz 4MB 80KB WEMOS D1 R1 (Retired) - d1_mini ESP8266 80MHz 4MB 80KB WeMos D1 R2 & mini - d1_mini_lite ESP8266 80MHz 1MB 80KB WeMos D1 mini Lite - d1_mini_pro ESP8266 80MHz 16MB 80KB WeMos D1 mini Pro -``` - -Since we know the MCU is an ESP32, not an ESP8266 we focus on the first table. The version we need is the `lolin32`. - -Create a new directory called `sound/` in the `01_arduino/` directory. - -Once you have created your project directory you should run the `init` _inside_ it, passing the IDs of the boards we want to use: - -```shell -$ platformio init --board nodemcuv2 --board lolin32 -``` - -You can use the `init` command multiple times to add additional boards. Add environments for every microcontroller board in your kit. - -This creates a project and defines multiple environments. You will need to add the **Native** environment manually by editing the `platformio.ini` file and adding: - -``` -[env:native] -platform = native -``` - -### 4.1 Test Your Understanding - -Create a program in your `sound/` directory to capture the noise level and display this in the Serial Monitor. diff --git a/01 Teambuilding.md b/01 Teambuilding.md deleted file mode 100644 index 04b510c..0000000 --- a/01 Teambuilding.md +++ /dev/null @@ -1,71 +0,0 @@ -# Professional Development - -Each week you will be expected to complete a series of lab activities in your two lab sessions. You will be required to reflect on these in your assignment so make sure you keep records of what you have done. - -Resources: - -1. [Lecture slides](https://docs.google.com/presentation/d/1qqetvLVMWvNGsmyGr9-Cuooxpz0Vl2OnD0oionqPOdI/edit) -2. Microsoft Teams installation files: - 1. [Official app](https://teams.microsoft.com/downloads) for MacOS and Windows 10. - 2. [Unofficial app](https://github.com/IsmaelMartinez/teams-for-linux) for Linux. - -## 1 Teams - -The agile teams have been set up to contain students with the range of skills needed to complete the module. Each team is named after an animal. Check the team list which you will find at the front of the lab to find out which team you have been assigned to and which lab slots you will need to attend (these should also be shown on your University timetable). - -1. Each team needs a catch phrase! Discuss and agree one for your team. -2. Early on in the _first lab session_ email any members of your team who have not turned up to remind them to attend. It it very important that you meet up _every scheduled lab_ to avoid falling behind! You will find their email addresses in the University Email address book. - -## 2 Project - -Make sure you understand the group project topic. Ask your _lab supervisors_ if you have any questions. The product is only worth **10%** of your final grade however the skills and knowledge you acquire by completing the weekly lab worksheets will be needed to complete the reflective report (40%) and revise for the phase test (50%). - -Carry out a brainstorm to make a list of all the interesting outcomes you could produce. You can find a list of the items in the IoT kit in the `exercises/` directory in the teaching materials on GitHub. - -The implementation will consist of three key parts: - -1. A "home hub" that contains the core business logic and handles the communications between the sensors/actuators and the UI. This could be a small computer running Linux (such as a Raspberry Pi) or a powerful microcontroller. -2. Some sensors and actuators that communicate with the hub. Each will need its own microcontroller and you will need to decide how it will wirelessly communicate with the hub. -3. Some form of UI that the homeowners can interact with. Will this be a web page, app or both? - -Discuss the technical strengths and weaknesses of your team members and, before the end of the first lab session make some tentative choices as to which part each person is best placed to work on. We will come back to this in the second lab. - -## 3 Skills Audit - -Perform a detailed analysis of the problem you are going to solve and perform a Skills Audit on your team. There are a list of generic skills listed in the presentation which you will need to supplement with skills related to your choice of project. use this [skills list](exercises/01_prof_dev/README.md) as a starting point. - -Create a **Team Competency Matrix** using a simple **Red-Amber-Green** (RAG) scale as shown in the lecture. This should include skills taken from the [skills list](exercises/01_prof_dev/README.md) provided plus any others you feel might be useful. - -Refine the matrix using a 5 point scale. - -## 4 Professional Development Plan - -This should be carried out in the second lab session in small groups of 2 or 3. In these smaller groups, develop a **Professional Development Plan** for each person who should identify three things they feel they need to learn before the start of the development process in week 3 (so don't be too ambitious). - -Create a top level heading for each of your chosen three topics and, for each, work together to answer the following questions, writing down the answers: - -1. What do I want to learn? -2. What will I do to achieve this? -3. What resources and support will I need? -4. What will my success criteria be? - -We will be reviewing this document in week 4 so keep it safe and refer to it as you carry out your learning. - -As you carry out your learning to support this, answer the following, writing the answers down as you do each piece of learning: - -1. What did you do? -2. Why? -3. What did you learn from this? -4. How will you be able to use this in the team project? - -## 5 Team Psychology - -Since we did not cover this in the lecture you should not attempt this task. We will come back to it in week 4. - -You have been introduced to a number of important (and potentially interesting?) areas of psychology that relate to group behaviour. As a group: - -1. Discuss the 'symptoms' of each (what should you be looking out for)? -2. What is the short-term impact on the team? -3. If not addressed what might be the longer-term impact? Is it recoverable at this stage? -4. What can be done to _prevent_ this from ocurring? -5. What can be done to recover it it occurs? diff --git a/02 Lab 1 Test-Driven Development.md b/02 Lab 1 Test-Driven Development.md deleted file mode 100644 index d13801c..0000000 --- a/02 Lab 1 Test-Driven Development.md +++ /dev/null @@ -1,101 +0,0 @@ - -# Test-Driven Development with Arduino - -In this lab you will learn how to carry out the process of Test-Driven development (TDD) using the Arduino framework. We will be using the PlatformIO command-line tools. There is [detailed documentation](https://docs.platformio.org/en/latest/plus/unit-testing.html#remote) covering the implementation of the [Unity](http://www.throwtheswitch.org/unity/) tools. - -## 1 Understanding the Code - -You should now use the IDE to open the `exercises/02_tdd/temp/` directory which contains a simple Arduino sketch with a library. Lets look at the files. As you can see there are some additional ones: - -``` -├── lib -│   ├── avg -│   │   ├── avg.cpp -│   │   └── avg.h -│   └── readme.txt -├── platformio.ini -├── readme.md -├── src -│   └── main.cpp -└── test - └── test_desktop - └── test_avg.cpp -``` - -1. The `lib/` directory contains our custom library. This is where we will build the business logic for our software. It will be thoroughly unit tested. -2. The `test/` directory contains the unit testing files that will be used to test the library code. - -## 2 Running the Unit Tests - -We will be executing our test suite from the terminal by invoking the `pio` command together with the `test` subcommand. Make sure you [create an account](https://docs.platformio.org/en/latest/userguide/account/cmd_register.html) and [log in](https://docs.platformio.org/en/latest/userguide/account/cmd_login.html). - -You should also ensure the `gcc` toolchain is installed on your computer. Run the command `gcc`. If this is not found you will need to install, the instructions differ depending on your operating system: - -1. MacOS: `brew install gcc` -2. Ubuntu: `apt install gcc` -3. Windows 10: install [Cygwin](https://sourceware.org/cygwin/) and make sure you pick the gcc tools from the selection of software it can install. - -```shell -$ pio test -v -e native - ================================== [SUMMARY] ================================== - Environment nodemcuv2 [SKIP] - Environment native [SUCCESS] - ========================= [SUCCESS] Took 0.32 seconds ========================= - - ===================== [test/test_desktop] Testing... (2/2) ===================== - /test_avg.cpp:11:test_add_single_val:FAIL: Expected 0 Was 42 [FAILED] - - ----------------------- - 1 Tests 1 Failures 0 Ignored - FAIL - =============================== [TEST SUMMARY] ================================ - test/test_desktop/env:nodemcuv2 [IGNORED] - test/test_desktop/env:native [FAILED] - ========================== [FAILED] Took 0.33 seconds ========================== -``` - -Notice that the test suite fails! - -## 3 Test-Driven Development - -You are now going to modify the code to ensure that the test passes. The test adds a single value to the library. It then reads the average value which should match the value we passed (but it doesn't). We are going to apply TDD principles. - -### 3.1 Define Requirements as a Test - -For this first iteration, this has already been done, look in the `test_avg.cpp` file. - -### 3.2 Write Code to pass the Test - -We now need to write just enough code to pass the test. Edit the `lib/avg/avg.cpp` file. Test your code by running the test suite. Stop as soon as the test passes. - -### 3.3 Refactor the Code - -The third and final step is to tidy up the code, making sure the tests still pass. - -### 3.4 Test Your Understanding - -Now apply the TDD principles to fix the following issues, this will take 6 TDD iterations: - -1. If I send 2 values to the library, the average should be calculated based on the 2 values. Try adding 42 and 24, it should return 33. - 1. If the result is wrong perhaps you needed to call the `avg_clear()` function at the start of each test. -2. If the average is a floating point number it should round up if the average is 0.5 or above: - 1. If I pass values of 42 and 23 the average should be 33. - 2. If I pass values of 42, 11, 17, the average should be 23. -3. The library should return the average of the last 5 values passed so if I add 6 values it should ignore the first one we added. - 1. If I pass the values 1, 2, 3, 4, 5 the average should be 3. - 2. If I pass the values 1, 2, 3, 4, 5, 6 the average should be 4. - 3. If I pass the values 1, 2, 3, 4, 5, 6, 7 the average should be 5. - -For an extension task, use TDD to implement an average function that returns the mean reading since the device was powered up. - -## 4 Integrate into an Arduino Project - -The final step is to use your custom library to create a complete temperature and humidity sensor. - -1. Connect a DHT11 sensor and capture the temperature and display in the serial monitor. - 2. If you are using the Lolin32 board you should also display the temperature on the screen. -2. Use your custom library to smooth the reading using a rolling average, display this next to each raw reading (including the screen if available). -3. Capture the humidity as well as temperature and display this next to the temp values. -4. How could you modify your library to smooth both the temperature and humidity? - 1. You may need to make changes to your library. - 2. Don't forget to apply the TDD methdology! diff --git a/02 MQTT CLI.md b/02 MQTT CLI.md deleted file mode 100644 index ad1716a..0000000 --- a/02 MQTT CLI.md +++ /dev/null @@ -1,79 +0,0 @@ -# Publish Subscribe - -Up to this point all the activities have been using the **HTTP Protocol**, which uses a _request-response_ process (the client requests a resource and the server responds with this resource). If this seems unfamiliar you should work through the HTTP Protocol worksheet. - -Whilst this approach works fine for delivering content to a web browser it is not a useful approach for certain applications. Imagine a chat room where you had to refresh the page to view new messages. - -In this worksheet you will learn how to use a new HTML5 **websocket** protocol that allows a full duplex (2 way) communication over a single TCP connection. We will then explore the **MQTT** protocol which can be run over websockets and is used to implement a _push message_ system, technically called _publish-subscribe_. - -## 1 Set Up - -Start by installing the [Mosquitto Tools](https://mosquitto.org/download). - -### 1.1 MacOS - -If you are using MacOS you should install the [Brew Package Manager](https://brew.sh) and use this to install Mosquitto using `brew install mosquitto`. - -### 1.2 Ubuntu - -If you are using Ubuntu you can install using the following commands: - -``` -sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa -sudo apt update -sudo apt install mosquitto-clients -``` - -### 1.3 Windows 10 - -If you are using Windows 10 you can download the 64 bit Binary exe and install. When you try running the commands you may need to include the **full path to the executable**. - -If (when) you encounter issues using Windows we recommend you either dual boot your computer or install [Virtual Box](https://www.virtualbox.org/wiki/Downloads) and use this to install [Ubuntu](https://www.ubuntu.com/download/desktop). There are [detailed instructions](https://askubuntu.com/questions/142549/how-to-install-ubuntu-on-virtualbox) online. - -## 2 The MQTT Protocol - -Now we have the tools installed we can start using the protocol. You have installed 2 tools, `mosquitto_pub` is used to publish messages and `mosquitto_sub` subscribes to a channel. We will use the `test.mosquitto.org` broker. - -Before connecting you will need to download the public key certificate that enables encryption between your computer and the broker. You can find this in the `exercises/MQTT` directory. Since the `mqtt.crt` file contains text this will display in the browser when selected rather than being downloaded. To solve this problem you should download the `mqtt.crt.zip` file and then unzip this to extract the key. Place this in a sensible directory on your computer such as documents. - -Nowpening _two_ terminal windows and in both of these navigate to the directory you placed the certificate file in: - -In the first window we will run the `mosquitto_sub` command and subscribe to a _topic_ called `302CEM/XXX` where `XXX` is your university username. Make sure you are running the commands in the same directory as the `mqtt.crt`. The correct password will be given out in the lab session. The topic should include your team name and your own username (replace the xxx). Note that on Windows computers you will need to include the full path to the `mosquitto_sub` command. - -```shell -$ mosquitto_sub -v -h mqtt.coventry.ac.uk -p 8883 --cafile mqtt.crt -u 302CEM -P xxx -t 302CEM/elephant/xxx -``` - -1. The `-v` is the verbose flag and this will force the program to display both the topic and message (if this is omitted it will only print the message). -2. The `-h` flag allows us to specify the _host_, in this case `test.mosquitto.org`. -3. The `-p` flag allows us to set the port (`1883` for non-secure connections and `8883` if the connection is encrypted). -4. The `--cafile` flag is where we tell the tool where the _server's public key_ is located. -5. The `-u` and `-P` flags are used to supply the username and password needed to validate the subscription. -6. The `-t` flag allows us to specify the _topic_, in this case `302CEM/elephant/XXX` (remember to substitute your team nane and username) - -The terminal will sit there, subscribed to the chosen topic, waiting to be sent some data which we will send using the second terminal window. - -In the second terminal we will run the `mosquitto_pub` command to publish messages to our topic. - -```shell -$ mosquitto_pub -h mqtt.coventry.ac.uk -p 8883 --cafile mqtt.crt -u 302CEM -P xxx -t 302CEM/elephant/xxx -m "hello world" -``` - -1. The `-m` flag allows us to specify the _message_, in this case `hello world`. - -If you look at the first terminal window (running `mosquitto_sub`) you should see your message displayed. - -The first terminal will continue to wait for messages until the command is exited by pressing ctrl+c. - -### 2.1 Test Your Understanding - -Working in small groups of between 2 and 4 people: - -1. Each member of the team should choose the same _topic name_ `302CEM/elephant`, substituting your team name. -2. Everyone runs the `mosquitto_sub` tool and subscribes to this same topic. -3. Each person launches a new terminal in a new pane (so you can see both terminal windows). -4. use the `mosquitto_pub` tool to send a message to your chosen _topic name_. -5. Look at the output of your `mosquitto_sub` command (in the first terminal window). -6. What happens if you subscribe to the `302CEM/` topic? - -What have you produced? Can you think of any application for this... diff --git a/02 MQTT JavaScript.md b/02 MQTT JavaScript.md deleted file mode 100644 index f3eee8b..0000000 --- a/02 MQTT JavaScript.md +++ /dev/null @@ -1,202 +0,0 @@ - -# Building Websites to Subscribe to MQTT Data - -This worksheet builds on the **Publish Subscribe** one. Make sure you have finished this before starting. In this worksheet you will learn how to use the TDD methodology to develop websites that subscribe to MQTT brokers. You can find the exercise files in the `exercises/02_tdd/web_client/` directory. - -## 1 Basic MQTT Client - -In this first exercise you will learn the basics of how to create a website that can subscribe to data from an MQTT broker. It will focus on writing JavaScript code that runs _inside the browser_. Open the `chat/` directory where you will see three files plus a directory. - -1. The `index.html` is the main webpage the user will see. You should open this in the browser to run the web app. - 1. It contains links to the **hivemq mqtt library** to allow the page to publish and subscribe. - 2. It links to the `module.js` script which contains our MVC Model. - 3. It links to the `mqtt.js` script that interacts with the html _view_ and JavaScript _model_. - 1. This is the MVC Controller and uses the `Messaging` object imported from the hivemq library to handle publishing to and subscribing from an MQTT broker which it does by creating a `client` object on line 6. This contains a number of properties that we can use to store anonymous functions, these will be triggered by different events, the most important being `onMessageArrived`. This property is assigned a function that gets triggered every time a new MQTT message arrives. This makes use of the functions in our model. - 2. At the bottom of the script we create an event listener that will get triggered once the html (the DOM) has been downloaded. This adds an event handler to the textbox that triggers each time a key on the keyboard is released. If the key is the enter key it retrieves the text in the textbox and passes it to the `publish()` function. - 3. The `publish()` function uses the `Messaging` object in the hivemq library to create a new `Message` object which is sent to the MQTT broker. -2. The `test/` directory contains the unit tests for our **MVC Model**. - 1. The `testrunner.html` runs the tests in the browser using the Jasmine 2 testing framework, you should open this file in your web browser. - 2. The `module.test.js` script contains the unit tests for the `module.js` script. - -As you can see you have a working website that conforms to the MVC design pattern plus a complete suite of unit tests that cover the model (business logic). - -### 1.1 Immediately-Invoked Function Expressions - -We are primarily concerned with writing tests for our _model_ (`module.js`) Open the file now and make sure you understand how it works. - -All variables in modern JavaScript are _function-scoped_, this means they are only accessible in the function they were declared in. Any variables defined outside a function have global scope. In our model we have an array to hold the messages which should not be directly accessed. To solve this we place the array declaration in an [anonymous function](http://helephant.com/2008/08/23/javascript-anonymous-functions/) which is stored in the `messages` constant. - -We obviously want any properties and methods we define to be able to see this array and so these need to be defined _in the same function_. Unfortunately any functions defined inside the main function will also not be accessible externally however remember we can return data from a function by using the `return` statement. In this example we return an object containing all the functions and properties we want to be able to call! - -To be able to access any of this we need to execute the function. To run a function we add a pair of parentheses at the end `()` and so by adding this to the end of the function expression it is immediately executed, hence the term **Immediately Executed Function Expression** or IIFE for short. Since all the data in a model should be private it is expected that any model you create will need to be defined as an IIFE. - -Take time to go through the code carefully so you fully understand how IIFEs work. If you decide to search online for additional resources (and you should) be aware that IIFEs used to be called **Function Closures** or Closures for short. - -### 1.2 TDD First Iteration - -Try leaving the text field blank then clicking on the button, what happens? Clearly we need to make changes to the model. The most obvious solution is to modify the `extractData()` function to throw an error if the message is a blank string. Although we are using the [Jasmine](https://jasmine.github.io) testing tools, these work in a very similar way to the [Jest](https://jestjs.io) tools. Open the `test/module.test.js` script and study it carefully noting that the tests have been placed in nested groups. - -#### 1.2.1 Write a Failing Test - -The first step is to define the functionality we want in the form of a test. Clearly we need to throw an error rather than simply add a blank item to the list. Since we are testing the add() function we need to add an extra test to this section of the suite. Locate the `extractData` tests which are grouped in the `method` group. Add the following test: - -```javascript -it('empty string parameter should throw an error', () => { - try { - messages.extractData('') - expect(1).toBe(0) // this line should not be run! - } catch(err) { - expect(err.message).toBe('empty string parameter') - } -}) -``` - -Notice that if the `extractData()` function does not throw an error it runs the next line which obviously fails. This means that we can flag if the error is not thrown. Run the unit test suite, the new test should fail, this is the first step. - -#### 1.2.2 Write Code to Pass the Test - -Your next step is to modify the `extractData()` function until all the tests pass. There is a solution below but see if you can do it without looking! - -```javascript -extractData: payloadString => { - if(payloadString.length === 0) { - throw new Error('empty string parameter') - } - return payloadString -} -``` - -#### 1.2.3 Refactor the Code - -The third and final step is to tidy up the code ensuring all the tests still pass. In this example there is only one line in the if statement block so we can reduce it to a single line as shown. - -```javascript -extractData: payloadString => { - if(payloadString.length === 0) throw new Error('empty string parameter') - return payloadString -} -``` - -Run the test suite again to make sure all the tests pass. You have now completed your first TDD iteration. - -### 1.3 TDD Second Iteration - -Try adding a message that only includes spaces, what happens? Use the TDD methodology to fix this bug (hint: try using the [`String.trim()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim) command). - -## 1.4 Test Your Understanding - -The current webpage has very limited functionality, only displaying the last message with no additional information. Use a TDD methodology to make the following improvements: - -1. change the topic, replacing the /cu segment with the chosen username. -2. store all the messages in the array rather than the last one by modifying the `addMessage()` function. -3. display the message thread in a table by modifying the `buildHTML()` function. -4. change the payload to an object containing the sender's username, message and the date/time and modify the `extractData()` function to return an object containing the three values. - You will also need to modify the `buildHTML()` function to avoid breaking your code. -5. Modify the `buildHTML()` function to: - 1. display the name of the sender in a second column in the table. - 2. display the date/time in a third column in the table. - -## 2 Maps - -The third and final topic will show you how we can use the data to place markers on Google Maps. - -[LatLon](https://www.latlong.net/) - -``` -mosquitto_pub -h broker.mqttdashboard.com -t cov/map -m '{"lat": 52.4082, "lon": -1.5071, "label": "cathedral"}' -``` - -| Location | Lat | Lon | -| ---------------------- | ------: | ------: | -| Godiva Statue | 52.4080 | -1.5104 | -| Frank Whittle Building | 52.4053 | -1.4998 | -| Police Station | 52.4045 | -1.5084 | -| Coventry College | 52.4140 | -1.5038 | -| University Hospital | 52.4213 | -1.4416 | - -need to create an array of markers to manage them. - -The `test/` directory contains a suite of tests to cover the code in the IIFE that you will find in the `module.js` script. Try running the tests, note that they all pass. - -### 2.1 TDD First Iteration - -need to handle incomplete data in the JSON string... missing label property. - -#### 2.1.1 Write a Failing Test - -By now you should be confortable with the TDD process. Let's add a third test for the `extractData` function. The following test should work: - -```javascript -it('throws exception if label property missing', () => { - try { - const str = '{"lat": 52.4082, "lon": -1.5071}' - maps.extractData(str) - expect(0).toBe(1) // this line should not run! - } catch(err) { - expect(err.message).toBe('Error: missing label property') - } -}) -``` - -Add this new test and use the testrunner to run the test suite. The test should fail with the message `Expected 0 to be 1` which shows that the error is not being thrown! - -#### 2.1.2 Write Code to Pass the Test - -Now we need to modify the `extractData()` function so that this new test passes (and we dont break any of the other tests!). Try the following: - -```javascript -extractData: payloadString => { - try { - const data = JSON.parse(payloadString) - if(data.label === undefined) { - throw new Error('missing label property') - } - return data - } catch(err) { - if(err.message === 'Unexpected token h in JSON at position 0') { - throw new Error('parameter is not a json string') - } - throw new Error(err) // we need to propagate all other errors - } -} -``` - -Run the test suite again to check that all the tests now pass. - -#### 2.1.3 Refactor the Code - -The third and final step in TDD is to refactor (tidy) the code, ensuring that the tests still pass. We can simplify the code by removing the brackets from single line `if` statements and clean up some of the conditionals. - -```javascript -try { - const data = JSON.parse(payloadString) - if(!data.label) throw new Error('missing label property') - return data -} catch(err) { - if(err.message === 'Unexpected token h in JSON at position 0') { - throw new Error('parameter is not a json string') - } - throw new Error(err) // we need to propagate all other errors -} -``` - -Make sure all the tests still pass before marking this task as complete. - -### 2.2 TDD Second (and third) Iteration - -Try modifying the script to handle a missing lat or lon property (note this will take two TDD iterations). - -### 2.3 Test Your Understanding - -The sample code demonstrates a simple map with multiple pins. You should now modify this to track buses around Coventry: - -1. Modify the `extractData()` function to accept and validate two additional pieces of data: - 1. `route` which is a number representing the bus route - 2. `reg` which should contain the vehicle registration number -2. Display both the route and reg number in the marker label. -3. Each `reg` should appear only once on the map: - 1. If the vehicle appears for the first time add a new pin. - 2. When the same vehicle updates its position you should replace the existing pin. -4. instead of using the generic marker you should instead use the following bus symbol as a [custom marker](https://developers.google.com/maps/documentation/javascript/custom-markers). Hint: add another property called `icon` whem you create a new `Marker`. - -![bus icon](exercises/.images/bus.png) diff --git a/02 MQTT Raspberry Pi.md b/02 MQTT Raspberry Pi.md deleted file mode 100644 index 03555b6..0000000 --- a/02 MQTT Raspberry Pi.md +++ /dev/null @@ -1,541 +0,0 @@ - -# Setting up the Raspberry Pi - -In this worksheet you will be shown how to setup and configure a raspberry pi as a central 'hub' for your home automation system. By the end of this you will have: - -1. The operating system (minibian) installed on the hub. -2. The I2C interface configured for use (and a small display attached). -3. A working MQTT broker installed (but not fully secured!). -4. The latest versions of Python and Pip. -5. A NodeJS runtime environment for running scripts. We will then use this to publish a simple API. - -## 1 Installing the Operating System - -In this worksheet we will be using the [Raspbian Stretch Lite distro](https://www.raspberrypi.org/downloads/raspbian/) which is a very cut down version of the [Debian Server](https://www.debian.org/distrib/). To complete this step you will need an SD card of at least 8GB that fits your Raspberry Pi, the size needs to be at least 4GB. Make sure you download the **lite** version (which should be around 370MB)! - -The download will be an `.img` file and needs to be burned onto the SD card. There are [detailed instructions](https://www.raspberrypi.org/documentation/installation/installing-images/) for the different OS you might be running on your laptop. - -On a Mac you will need the following commands, google them to understand what they do: - -``` -diskutil list external physical find the drive number. -diskutil randomDisk diskX formats disk, replace X with the drive number. - sudo dd bs=1m if=2018-11-13-raspbian-stretch-lite.img of=/dev/disk3 burns the specified image to the specified drive. -``` - -Once you have installed the image, insert it into the RPi, connect a network cable, keyboard and monitor plus a suitable MicroUSB power supply then you can boot up the computer. Once you have booted to the login prompt you can log in, username pi password raspberry. - -### 1.1 Connecting Using SSH Over USB - -At this stage you would normally need to plug in a keyboard and monitor before booting the device. If you don't have the facilities to do this (or fancy a challenge) you can configure your device to allow you to plug the Pi into your computer using a USB cable and secure shell into it over this cable. - -With the USB card still inserted into your laptop, open it and locate the `confg.txt` file, open it in a suitable editor such as VS Code and add the following line to the end: - -``` -dtoverlay=dwc2 -``` - -The next file we alter is cmdline.txt, but it is a bit different. Parameters in this file are not delimited by new lines or commas, they are delimited by space characters. In this file we want to add the following after the `rootwait` parameter: - -``` -modules-load=dwc2,g_ether -``` - -Finally we want to enable SSH. By default this is disabled so, for the first connection we override this by creating an empty text file called `ssh` on the SD card (no file extension). - -### 1.2 Resizing the Partition - -When you install the image it only uses a small part of the SD card. Your first task is to install the `raspi-config` tool. - -``` -apt update -apt upgrade -y -apt install -y apt-utils raspi-config - -raspi-config -``` - -This will launch the config program. Choose the **Advanced** option from the menu and the option to extend the partition. Once this is done you need to exit the config program then restart the server. - -_PRO TIP: there is a subcommand called `nonint` (non-interactive) which supports commands that correspond with the options you select in the interactive tool, these are now [documented](https://raspberrypi.stackexchange.com/questions/28907/how-could-one-automate-the-raspbian-raspi-config-setup). By using the subcommands you can automate the process by creating a shell script. To extend the partition you would run the command:_ - -``` -raspi-config nonint do_expand_rootfs -``` - -If you change to partition tables you need to restart the server for the changes to take effect. - -``` -reboot -``` - -When the system has rebooted and you have logged in, check that the main partition is as big as possible: - -``` -df -h -``` - -### 1.3 Changing the Host Name - -Every device on the network is configured with a _host name_. If you run the `hostname` command you can see that this defaults to `minibian`. Since every raspberry pi running the Minibian distro could have the same name this is not very satisfactory! Run the `raspi-config` tool again and note the second menu item, `Hostname`. Select this. The next screen contains detailed instructions, click OK once you have read these. - -On the next screen you can delete the existing name and enter your own. For the purposes of this module you should make the hostname your team's animal name in lowercase, for example `elephant`. If you exit the tool you will be asked if you want to reboot, do this. - -Once the system has rebooted and you are logged in, run the `hostname` command to check this has updated. - -_PRO TIP: Use the `raspi-config nonint` subcommand to set the hostname:_ - -``` -raspi-config nonint do_hostname elephant -``` - -### 1.4 Enabling SSH - -Since we want to run the server headles (no keyboard, mouse and monitor) we need to enable SSH to allow us to connect remotely. This is done using the `raspi-config` tool and accessing the _interfacing options_ menu. Make sure you complete this step! - -_PRO TIP: use the raspi-config nonint_ subcommand to enable SSH:_ - -``` -raspi-config nonint do_ssh 0 -``` - -### 1.5 Installing Key Packages - -Now we need to install a number of important packages: - -``` -apt install -y apt-transport-https rsync sudo nano git tree curl software-properties-common mc build-essential libssl-dev libffi-dev i2c-tools -``` - -### 1.6 Creating a Normal User - -Up to now we have been logging in as `root`, this is both insecure and dangerous. In this section we will be creating a user with standard permissions then adding them to the _sudoers_ group so they can execute commands as root if needed. In this example the username is `userx` but you should change this to whatever you want. - -1. The `-m` flag tells the computer to create the home directory if it does not exist. -2. The `-d` flag tells the computer to make the `/home/userx` directory the default home directory. -3. The `-s` flag indicates that the default shell should be `bash`. -4. The `-c` flag is a comment attached to the account. -5. Finally we specify the username. - -Once the account is created we need to set its password and add it to the __sudoers_ group so that we can execute commands that need root permissions. - -``` -useradd -m -d /home/userx -s /bin/bash -c "userx account" userx -passwd userx -usermod -aG sudo userx -``` - -_PRO TIP: changing a user's password required you to type the password into the terminal (using stdin). To automate this process in a shell script you need to pipe a string to the `chpasswd` command. This means you won't be prompted for the password._ - -``` -echo 'userx:mysecurepw'|chpasswd -``` - -We should also take the opportunity to change the root password to something a little less _default_. You should make this password very difficult to guess but then make sure you keep a record of this. You will rarely ever need to log in using this root account. - -``` -passwd -``` - -Now log out of the root account and log in using your new user account. - -## 2 Configuring I2C - -Next we will configure the I2C interface so that you can attach sensors that make use of it. By the end of this section you should have a screen that displays the computer host name and ip address whenever you power it on. We will also explore how to capture data from an I2C enabled sensor. - -Start by running the `raspi-config` command. This time access the _interface options_ and choose `Enable/Disable automatic loading of I2C kernel module` to enable I2C. After exiting the tool you need to reboot. We are now no longer logged in as `root` but rebooting requires root permissions. Since we are part of the _sudoers_ group we can run a command with root privileges by prefixing it with the `sudo` keyword. - -_PRO TIP: use the `raspi-config` tool in non-interactive mode to enable I2C:_ - -``` -sudo raspi-config nonint do_i2c 0 -``` - -``` -sudo reboot -``` - -When it has rebooted, log in again using your normal user account. - -### 2.1 Fixing I2C Permissions - -By default, the I2C bus is only accessible if you use root permissions. The problem is that we don't want to run all our python scripts as root! To fix this you need to edit the `/lib/udev/rules.d/60-i2c-tools.rules` file using the nano text editor. - -``` -sudo nano /lib/udev/rules.d/60-i2c-tools.rules -``` - -Notice that we have to edit the file with root privileges. The Raspberry Pi includes two I2C buses, labelled `i2c-0` and `i2c-1`, We will be using bus 1. Replace the existing contents with the following: - -``` -KERNEL=="i2c-0" , GROUP="i2c", MODE="0660" -KERNEL=="i2c-[1-9]*", GROUP="i2c", MODE="0666" -``` - -This splits this so that the permissions are retained for interface 0 but every user can access all the others (bus 1). - -### 2.2 Changing the I2C Baud Rate - -By default the I2C bus runs at a slow 100Kb/s speed however the Raspberry Pi has a "fast mode" (400Kb/s) driver. To enable this we need to edit the `/boot/config.txt` file using root privileges: - -``` -sudo nano /boot/config.txt -``` - -modify the following line: - -``` -dtparam=i2c_arm=on,i2c_arm_baudrate=400000 -``` - -Having made our changes we need to restart the server. - -### 2.3 Connecting an OLED Screen - -There is a command called `i2cdetect` which scans an I2C but looking for attached devices. We will be using I2C bus 1 so we run the following command: - -``` -$ sudo i2cdetect -y 1 - 0 1 2 3 4 5 6 7 8 9 a b c d e f - 00: -- -- -- -- -- -- -- -- -- -- -- -- -- - 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 70: -- -- -- -- -- -- -- -- -``` - -As you can see, no devices are detected. - -Now lets check the I2C bus is configured correctly by wiring up a small OLED screen. You should find one in your electronics kit. Notice that it has 4 pins labelled `GND`, `VCC`, `SCK`, `SDA`. These need to be connected to the matching pins on the Raspberry Pi header. Below you can see the pins labelled. This labelling applies to both the RPi v2 and v3. If you look carefully at the diagram you can see that the pins connected to the `I2C-1` bus are clearly labelled: - -1. Pin 6 is labelled `GND`, this should be connected to the `GND` pin on the screen. -2. Pin 4 is labelled `5V PWR`, this should be connected to the `VCC` pin. -3. Pin 5 is labelled `I2C SCL`, this should be connected to the `SCK` pin. -4. Pin 3 is labelled `I2C1 SDA`, this should be connected to the `SDA` pin. - -![Raspberry Pi 2 Pinout](exercises/.images/rp2_pinout.png) - -If we run the `i2cdetect` command again we should see that the screen is detected and is using I2C address `0x3c`. - -``` -$ sudo i2cdetect -y 1 - 0 1 2 3 4 5 6 7 8 9 a b c d e f - 00: -- -- -- -- -- -- -- -- -- -- -- -- -- - 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- - 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 70: -- -- -- -- -- -- -- -- -``` - -This demonstrates both that the i2c bus is configured correctly and that the screen is working. - -### 2.4 Writing to the Screen - -Finally we can create a simple python script to test out the screen. We first need to install a couple of packages and then some libraries. The first is the Adafruit SSD1306 library that is needed to control the screen. - -``` -sudo apt install -y python-pip python-imaging python-dev python-smbus -``` - -``` -git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git -cd Adafruit_Python_SSD1306 -sudo python setup.py install -``` - -The second is the GPIO library that needs to be installed using the pip package tool: - -``` -sudo pip install RPi.GPIO -``` - -Create a new script in your home directory on the Raspberry Pi and call it `oled.py`. Open it in the nano editor and paste in the contents of `oled.py` which you can find in the `exercises/01_rpi/` directory, save and exit from nano. - -At the moment the script is not executable so, before running it we need to set the execution flag on the file: - -``` -chmod +x oled.py -./oled.py -``` - -If you look at the screen you should see a message... - -### 2.5 Running a Script at Boot - -The final task in this section is to create a script that displays the hostname and ip address on the screen when the raspberry pi first boots. The first task is to create a script in the `/bin/` directory. - -``` -sudo nano /bin/network.py -``` - -Copy in the contents of the `network.py` script, save and quit nano. Now you need to make the file executable. - -``` -sudo chmod +x /bin/network.py -``` - -If we want the script to run automatically we need to add it as a _cron_ task. We do this by running the `crontab -e` command, this opens the _crontab_ file. Add the following to the end: - -``` -@reboot python /bin/network.py & -``` - -This tells the crontab to run the script when the device boots. The `&` character runs the script in the background. Try rebooting the server, you should see the information displayed as soon as the reboot is complete. - -## 3 Connecting using Secure Shell - -Up to this point we have connected a monitor and keyboard to our server and used this to interact with the system. Most servers run _headless_ and we connect remotely using secure shell (ssh). To do this we need to know the _hostname_ or the _ip address_ of the system. Thanks to the previous step, every time we boot the server both these pieces of information are displayed on the attached OLED screen! - -Start by disconnecting the screen and keyboard and reconnecting any cables you removed in the first place... - -If you are using a Mac or Linux laptop you connect using the ssh command through the terminal: - -``` -$ ssh userx@elephant -``` - -You will be prompted for your password and, the first time you connect, the server will attempt to send you its public encryption key, you will be asked if you want to accept this. - -If the credentials are correct you are now connected to the server and all the commands you enter will be run on it. To quit and return to your computer enter the `exit` command. - -If you are using Windows you will probably need to download the [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) application. After launch you need to enter the hostname and user credentials in the appropriate boxes. - -From now onwards you should always connect using SSH (you will never need to plug in the keyboard and monitor). - -## 4 Installing an MQTT Broker - -Now we will install (and partially secure) a [Mosquitto MQTT broker](https://mosquitto.org/) so that data can be published to it and the client can subscribe to and receive data. We will be installing this using the `apt` command however the version installed by default is quite old and does not support the latest MQTT features. To resolve this we will add a package repository containing the more recent version. We need the version that matches the version of Debian we have installed. In the example below, the response from the first command indicates we are running `jessie` so the url when we retrieve the list points to the jessie version. If you get a different result, change the URL to match. - -``` -$ cat /etc/os-release - VERSION="8 (jessie)" -$ wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key -$ sudo apt-key add mosquitto-repo.gpg.key - OK -$ cd /etc/apt/sources.list.d/ -$ sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list -cd ~ -``` - -Once this is done we can update the cached package list and install the mosquitto server and the client tools. - -``` -sudo apt update -sudo apt search mosquitto -sudo apt install mosquitto mosquitto-clients -mosquitto_pub -``` - -This last command tries to run the mosquitto publish tool with no parameters. This will show the help page. We know we have the latest version if we can see a `--cafile` flag listed. To see if the server is running (on its default port of `1883`) we can run: - -### 4.1 Managing the Service - -``` -$ netstat -at - Active Internet connections (servers and established) - Proto Recv-Q Send-Q Local Address Foreign Address State - tcp 0 0 *:ssh *:* LISTEN - tcp 0 0 *:1883 *:* LISTEN - tcp 0 208 elephant:ssh local-comp:55951 ESTABLISHED - tcp6 0 0 [::]:ssh [::]:* LISTEN - tcp6 0 0 [::]:1883 [::]:* LISTEN <-- -``` - -Notice the last line, this shows the service is running on port `1883`. - -Whenever you update the configuration you need to restart the service. Here are the commands to stop start and restart: - -``` -sudo /etc/init.d/mosquitto stop -sudo /etc/init.d/mosquitto start -sudo /etc/init.d/mosquitto restart -``` - -### 4.2 Publishing and Subscribing - -Now we have the MQTT Broker configured we need to learn how to publish messages to and subscribe to published messages. - -You should be able to use the `mosquitto-clients` tools covered in the previous lab. Remember that the broker is currently not secure and so will run on port `1883`. The hostname will be the one you assigned to the server earlier in the lab and of course you won't need to specify username, password or CA file. - -The server is logging its activity to the `/var/log/mosquitto/mosquitto.log` file. Linux allows you to see the last entries in the log file using the `tail` command. To see a live, updating you can add the `-f` (follow) flag. - -``` -sudo tail -f /var/log/mosquitto/mosquitto.log -``` - -Run this command on the server and see what gets logged when you publish and subscribe. If you are getting any errors with the mosquitto tools you should check this log to find out the cause. - -## 5 Securing the Broker - -Although the broker does work it lacks any form of security. In this section we will be correcting this. Under linux, all system-related configuration files are in the `/etc` directory and, if you study its contents, you will find a `mosquitto` subdirectory. This is where we access all the config settings for the broker. In the rest of this section all files we mention are in this directory. - -### 5.1 User Accounts - -The first step is to add some usernames and passwords. The mosquitto server comes with the `mosquitto_passwd` command to allow us to add multiple user accounts. These are stored in the `passwd` text file. The file is only read-only for non-root users. Use the following command to add a new user, substituting the chosen username and password where shown. - -``` -sudo touch /etc/mosquitto/passwd -sudo mosquitto_passwd -b /etc/mosquitto/passwd username password -``` - -You will also need to modify your config file to prevent anonymous use and tell it where to find the password file. Edit the `mosquitto.conf` file and add the following two lines: - -``` -allow_anonymous false -password_file /etc/mosquitto/passwd -``` - -Once you have added users you need to restart the broker for the changes to take effect. - -After restarting the server you will need to supply a valid username and password when you connect. Try publishing and subscribing to check this is true. - -### 5.2 Access Control List - -You have probably noticed that even with multiple accounts, all of these can publish and subscribe to any topic. Since we want to introduce some privacy we need to create an _access control list_ which defines which topics can be published to (written) or subscribed to (read). You should create a new file in the `/etc/mosquitto/` directory called `acl`. You will need root permissions to do this. - -``` -sudo nano /etc/mosquitto/acl -``` - -You should then define the access permissions for the different accounts. In the example below we have two user accounts called `house` and `garden`. You can assign one of three permissions: - -1. `read` means the user can _subscribe_ to the topic. -2. `write` means the user can _publish_ to the topic. -3. `readwrite` means the user can both publish and subscribe to the topic. - -The `#` character signifies a wildcard (any combination of topic segments). - -``` -user house -topic readwrite house/# - -user garden -topic readwrite garden/# - -user powerx -topic readwrite powerx/# - -user 4009user -topic readwrite 4009user/# -topic readwrite owntracks/# -``` - -Once you have added the appropriate access permissions we need to let mosquitto know the access control list exists. Edit the `/etc/mosquitto/mosquitto.conf` file and add the following line: - -``` -acl_file /etc/mosquitto/acl -``` - -Restart the broker for the changes to take effect. Now try to publish and subscribe both to topics in and not in the access control list. Notice that if you try to publish or subscribe off-topic you dont get an error but the action will fail. - -### 5.3 Implementing SSL - -The final step is to implement SSL to ensure the data is encrypted as it passes between the broker and clients. Let's Encrypt is a new service offering free SSL certificates through an automated API. - -``` -wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh -``` - --------- - -### 5.3 Implementing SSL (self signed) - -The final step is to implement SSL to ensure data is encrypted as it passes between the broker and client. - -#### 5.3.1 Installing OpenSSL - -**Warning: depending on the speed of the Raspberry Pi, thie process of building OpenSSL can take several hours to complete. It is recommended that you run the installation step overnight.** - -OpenSSL is a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library. It is needed to generate the required certificates. We need to ensure we are always using the latest version and so, rather than install from a repository we will build from source. - -``` -git clone git://git.openssl.org/openssl.git -cd openssl -./config -make -make test -sudo make install -``` - -#### 5.3.2 Generating the Certificates - -On most Linux distros, the certificates are typically stored in the `/etc/ssl/` directory so we need to create this and navigate to it. Note you may need root privileges to create the directory if it does not already exist. - -``` -mkdir /etc/ssl/ -cd /etc/ssl/ -``` - -Now we need to create a 2048-bit key called `mosq-ca.key` and use this to create an X509 certificate. During the second step you will be asked a series of questions, it doesn't matter what you enter. - -``` -sudo openssl genrsa -out mosq-ca.key 2048 -sudo openssl req -new -x509 -days 365 -key mosq-ca.key -out mosq-ca.crt -``` - -Next we create the private key and use this to create the Certificate Signing Request (CSR). Note you will need to enter the same information a second time. - -``` -sudo openssl genrsa -out mosq-serv.key 2048 -sudo openssl req -new -key mosq-serv.key -out mosq-serv.csr -``` - -Normally this would be sent to the Certification authority that, after verifying the author identity, returns a certificate but in this example we will use a self-signed certificate and verify the certificate. - -``` -sudo openssl x509 -req -in mosq-serv.csr -CA mosq-ca.crt -CAkey mosq-ca.key -CAcreateserial -out mosq-serv.crt -days 365 -sha256 -sudo openssl x509 -in mosq-serv.crt -noout -text -``` - -#### 5.3.3 Configuring the Broker - -Now the certificates are ready we have to configure MQTT Mosquitto Server so that it can use these certificates by editing the `mosquitto.conf` file and adding the following to the end. - -``` -listener 8883 -cafile /etc/ssl/mosq-ca.crt -certfile /etc/ssl/mosq-serv.crt -keyfile /etc/ssl/mosq-serv.key -``` - -Restarting the broker will put the changes into effect, you should see that this is now running over port 8883. If you want to connect to the broker now you will need to download the `mosq-ca.crt` certificate and use this when making connections to the broker. - -One way to download the certificate is to log out of the server and use the rsync tool to copy the file to your computer using the ssh connection. For example the following command copies the file to the `~/Documents` directory on the local workstation: - -``` -rsync -avzhe ssh root@elephant:/etc/ssl/mosq-ca.crt ~/Documents/ -``` - -### 5.4 Configuring Websockets - -The server is now configured as an MQTT broker however if you plan to use a browser to connect to it you will need to enable _MQTT over Websocket__. You will need to enable this in your `mosquitto.conf` configuration file by adding the following: - -``` -listener 9001 -protocol websockets -``` - -Rather than restarting the broker this time we will tell it to use our updated config file. Run the command: - -``` -$ mosquitto -c /etc/mosquitto/mosquitto.conf - opening websockets listen socket on port 9001 - opening ipv4 listen socket on port 8883 - opening ipv6 listen socket on port 8883 -``` - -When you restart the broker you should see that it is now running a websocket connection over port 9001 as well as the standard MQTT connection on port 8883. - -## References - -https://www.thepolyglotdeveloper.com/2016/06/connect-raspberry-pi-zero-usb-cable-ssh/ - -https://dzone.com/articles/mqtt-security-securing-a-mosquitto-server - -http://www.steves-internet-guide.com/mqtt-websockets/ diff --git a/02 Using the I2C Protocol.md b/02 Using the I2C Protocol.md new file mode 100644 index 0000000..38980a8 --- /dev/null +++ b/02 Using the I2C Protocol.md @@ -0,0 +1,148 @@ +# Using the I2C Protocol + +In this tutorial we will configure the I2C interface so that you can attach sensors that make use of it. By the end of this section you should have a screen that displays the computer host name and ip address whenever you power it on. We will also explore how to capture data from an I2C enabled sensor. The materials assume you have already built a base server by following the instructions in the **Getting Started** tutorial. If you have not completed this do it now. + +## 1 Enabling the I2C Interface + +Out of the box the I2C interface is disabled by default. Out first step is therefore to enable this interface. + +Start by running the `raspi-config` command. This time access the _interface options_ and choose `Enable/Disable automatic loading of I2C kernel module` to enable I2C. After exiting the tool you need to reboot. We are now no longer logged in as `root` but rebooting requires root permissions. Since we are part of the _sudoers_ group we can run a command with root privileges by prefixing it with the `sudo` keyword. + +After enabling the interface exit the `raspi-config` tool, you will be asked to reboot the server and this will be needed to activate the I2C interface. + +When it has rebooted, log in. + +### 1.1 Fixing I2C Permissions + +By default, the I2C bus is only accessible if you use root permissions. The problem is that we don't want to run all our python scripts as root! To fix this you need to edit the `/lib/udev/rules.d/60-i2c-tools.rules` file using the nano text editor. + +``` +sudo nano /lib/udev/rules.d/60-i2c-tools.rules +``` + +Notice that we have to edit the file with root privileges. The Raspberry Pi includes two I2C buses, labelled `i2c-0` and `i2c-1`, We will be using bus 1. Replace the existing contents with the following: + +``` +KERNEL=="i2c-0" , GROUP="i2c", MODE="0660" +KERNEL=="i2c-[1-9]*", GROUP="i2c", MODE="0666" +``` + +This splits this so that the permissions are retained for interface 0 but every user can access all the others (bus 1). + +### 1.2 Changing the I2C Baud Rate + +By default the I2C bus runs at a slow 100Kb/s speed however the Raspberry Pi has a "fast mode" (400Kb/s) driver. To enable this we need to edit the `/boot/config.txt` file using root privileges: + +``` +sudo nano /boot/config.txt +``` + +modify the following line: + +``` +dtparam=i2c_arm=on,i2c_arm_baudrate=400000 +``` + +Having made our changes we need to restart the server. + +### 1.3 Scanning for I2C Devices + +There is a command called `i2cdetect` which scans an I2C but looking for attached devices. We will be using I2C bus 1 so we run the following command: + +``` +$ sudo i2cdetect -y 1 + 0 1 2 3 4 5 6 7 8 9 a b c d e f + 00: -- -- -- -- -- -- -- -- -- -- -- -- -- + 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 70: -- -- -- -- -- -- -- -- +``` + +As you can see, no devices are detected. You should now move on to either section 2 where we configure a small OLED screen or section 3 where we configure a simple sensor and read in data from it. + +## 2 Connecting an OLED Screen + +Now lets check the I2C bus is configured correctly by wiring up a small OLED screen. You should find one in your electronics kit. Notice that it has 4 pins labelled `GND`, `VCC`, `SCK`, `SDA`. These need to be connected to the matching pins on the Raspberry Pi header. Below you can see the pins labelled. This labelling applies to both the RPi v2 and v3. If you look carefully at the diagram you can see that the pins connected to the `I2C-1` bus are clearly labelled: + +1. Pin 6 is labelled `GND`, this should be connected to the `GND` pin on the screen. +2. Pin 4 is labelled `5V PWR`, this should be connected to the `VCC` pin. +3. Pin 5 is labelled `I2C SCL`, this should be connected to the `SCK` pin. +4. Pin 3 is labelled `I2C1 SDA`, this should be connected to the `SDA` pin. + +![Raspberry Pi 2 Pinout](exercises/.images/rp2_pinout.png) + +If we run the `i2cdetect` command again we should see that the screen is detected and is using I2C address `0x3c`. + +``` +$ sudo i2cdetect -y 1 + 0 1 2 3 4 5 6 7 8 9 a b c d e f + 00: -- -- -- -- -- -- -- -- -- -- -- -- -- + 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- + 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + 70: -- -- -- -- -- -- -- -- +``` + +This demonstrates both that the i2c bus is configured correctly and that the screen is working. + +### 2.4 Writing to the Screen + +Finally we can create a simple python script to test out the screen. We first need to install a couple of packages and then some libraries. The first is the Adafruit SSD1306 library that is needed to control the screen. + +``` +sudo apt install -y python-pip python-imaging python-dev python-smbus +``` + +``` +git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git +cd Adafruit_Python_SSD1306 +sudo python setup.py install +``` + +The second is the GPIO library that needs to be installed using the pip package tool: + +``` +sudo pip install RPi.GPIO +``` + +Create a new script in your home directory on the Raspberry Pi and call it `oled.py`. Open it in the nano editor and paste in the contents of `oled.py` which you can find in the `exercises/01_rpi/` directory, save and exit from nano. + +At the moment the script is not executable so, before running it we need to set the execution flag on the file: + +``` +chmod +x oled.py +./oled.py +``` + +If you look at the screen you should see a message... + +### 2.5 Running a Script at Boot + +The final task in this section is to create a script that displays the hostname and ip address on the screen when the raspberry pi first boots. The first task is to create a script in the `/bin/` directory. + +``` +sudo nano /bin/network.py +``` + +Copy in the contents of the `network.py` script, save and quit nano. Now you need to make the file executable. + +``` +sudo chmod +x /bin/network.py +``` + +If we want the script to run automatically we need to add it as a _cron_ task. We do this by running the `crontab -e` command, this opens the _crontab_ file. Add the following to the end: + +``` +@reboot python /bin/network.py & +``` + +This tells the crontab to run the script when the device boots. The `&` character runs the script in the background. Try rebooting the server, you should see the information displayed as soon as the reboot is complete. + +## 3 Reading Data from a Sensor diff --git a/03 Creating an MQTT Broker.md b/03 Creating an MQTT Broker.md new file mode 100644 index 0000000..1791485 --- /dev/null +++ b/03 Creating an MQTT Broker.md @@ -0,0 +1,312 @@ +# Installing an MQTT Broker + +Now we will install (and partially secure) a [Mosquitto MQTT broker](https://mosquitto.org/) so that data can be published to it and the client can subscribe to and receive data. We will be installing this using the `apt` command however the version installed by default is quite old and does not support the latest MQTT features. To resolve this we will add a package repository containing the more recent version. We need the version that matches the version of Debian we have installed. In the example below, the response from the first command indicates we are running `jessie` so the url when we retrieve the list points to the jessie version. If you get a different result, change the URL to match. + +``` +$ cat /etc/os-release + VERSION="8 (jessie)" +$ wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key +$ sudo apt-key add mosquitto-repo.gpg.key + OK +$ cd /etc/apt/sources.list.d/ +$ sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list +cd ~ +``` + +Once this is done we can update the cached package list and install the mosquitto server and the client tools. + +``` +sudo apt update +sudo apt search mosquitto +sudo apt install mosquitto mosquitto-clients +mosquitto_pub +``` + +This last command tries to run the mosquitto publish tool with no parameters. This will show the help page. We know we have the latest version if we can see a `--cafile` flag listed. To see if the server is running (on its default port of `1883`) we can run: + +### 4.1 Managing the Service + +``` +$ netstat -at + Active Internet connections (servers and established) + Proto Recv-Q Send-Q Local Address Foreign Address State + tcp 0 0 *:ssh *:* LISTEN + tcp 0 0 *:1883 *:* LISTEN + tcp 0 208 elephant:ssh local-comp:55951 ESTABLISHED + tcp6 0 0 [::]:ssh [::]:* LISTEN + tcp6 0 0 [::]:1883 [::]:* LISTEN <-- +``` + +Notice the last line, this shows the service is running on port `1883`. + +Whenever you update the configuration you need to restart the service. Here are the commands to stop start and restart: + +``` +sudo /etc/init.d/mosquitto stop +sudo /etc/init.d/mosquitto start +sudo /etc/init.d/mosquitto restart +``` + +### 4.2 Publishing and Subscribing + +Now we have the MQTT Broker configured we need to learn how to publish messages to and subscribe to published messages. + +You should be able to use the `mosquitto-clients` tools covered in the previous lab. Remember that the broker is currently not secure and so will run on port `1883`. The hostname will be the one you assigned to the server earlier in the lab and of course you won't need to specify username, password or CA file. + +The server is logging its activity to the `/var/log/mosquitto/mosquitto.log` file. Linux allows you to see the last entries in the log file using the `tail` command. To see a live, updating you can add the `-f` (follow) flag. + +``` +sudo tail -f /var/log/mosquitto/mosquitto.log +``` + +Run this command on the server and see what gets logged when you publish and subscribe. If you are getting any errors with the mosquitto tools you should check this log to find out the cause. + +## 5 Securing the Broker + +Although the broker does work it lacks any form of security. In this section we will be correcting this. Under linux, all system-related configuration files are in the `/etc` directory and, if you study its contents, you will find a `mosquitto` subdirectory. This is where we access all the config settings for the broker. In the rest of this section all files we mention are in this directory. + +### 5.1 User Accounts + +The first step is to add some usernames and passwords. The mosquitto server comes with the `mosquitto_passwd` command to allow us to add multiple user accounts. These are stored in the `passwd` text file. The file is only read-only for non-root users. Use the following command to add a new user, substituting the chosen username and password where shown. + +``` +sudo touch /etc/mosquitto/passwd +sudo mosquitto_passwd -b /etc/mosquitto/passwd username password +``` + +You will also need to modify your config file to prevent anonymous use and tell it where to find the password file. Edit the `mosquitto.conf` file and add the following two lines: + +``` +allow_anonymous false +password_file /etc/mosquitto/passwd +``` + +Once you have added users you need to restart the broker for the changes to take effect. + +After restarting the server you will need to supply a valid username and password when you connect. Try publishing and subscribing to check this is true. + +### 5.2 Access Control List + +You have probably noticed that even with multiple accounts, all of these can publish and subscribe to any topic. Since we want to introduce some privacy we need to create an _access control list_ which defines which topics can be published to (written) or subscribed to (read). You should create a new file in the `/etc/mosquitto/` directory called `acl`. You will need root permissions to do this. + +``` +sudo nano /etc/mosquitto/acl +``` + +You should then define the access permissions for the different accounts. In the example below we have two user accounts called `house` and `garden`. You can assign one of three permissions: + +1. `read` means the user can _subscribe_ to the topic. +2. `write` means the user can _publish_ to the topic. +3. `readwrite` means the user can both publish and subscribe to the topic. + +The `#` character signifies a wildcard (any combination of topic segments). + +``` +user house +topic readwrite house/# + +user garden +topic readwrite garden/# + +user powerx +topic readwrite powerx/# + +user 4009user +topic readwrite 4009user/# +topic readwrite owntracks/# +``` + +Once you have added the appropriate access permissions we need to let mosquitto know the access control list exists. Edit the `/etc/mosquitto/mosquitto.conf` file and add the following line: + +``` +acl_file /etc/mosquitto/acl +``` + +Restart the broker for the changes to take effect. Now try to publish and subscribe both to topics in and not in the access control list. Notice that if you try to publish or subscribe off-topic you dont get an error but the action will fail. + +### 5.3 Implementing SSL + +The final step is to implement SSL to ensure the data is encrypted as it passes between the broker and clients. Let's Encrypt is a new service offering free SSL certificates through an automated API. + +``` +wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh +``` + +-------- + +### 5.3 Implementing SSL (self signed) + +The final step is to implement SSL to ensure data is encrypted as it passes between the broker and client. + +#### 5.3.1 Installing OpenSSL + +**Warning: depending on the speed of the Raspberry Pi, thie process of building OpenSSL can take several hours to complete. It is recommended that you run the installation step overnight.** + +OpenSSL is a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library. It is needed to generate the required certificates. We need to ensure we are always using the latest version and so, rather than install from a repository we will build from source. + +``` +git clone git://git.openssl.org/openssl.git +cd openssl +./config +make +make test +sudo make install +``` + +#### 5.3.2 Generating the Certificates + +On most Linux distros, the certificates are typically stored in the `/etc/ssl/` directory so we need to create this and navigate to it. Note you may need root privileges to create the directory if it does not already exist. + +``` +mkdir /etc/ssl/ +cd /etc/ssl/ +``` + +Now we need to create a 2048-bit key called `mosq-ca.key` and use this to create an X509 certificate. During the second step you will be asked a series of questions, it doesn't matter what you enter. + +``` +sudo openssl genrsa -out mosq-ca.key 2048 +sudo openssl req -new -x509 -days 365 -key mosq-ca.key -out mosq-ca.crt +``` + +Next we create the private key and use this to create the Certificate Signing Request (CSR). Note you will need to enter the same information a second time. + +``` +sudo openssl genrsa -out mosq-serv.key 2048 +sudo openssl req -new -key mosq-serv.key -out mosq-serv.csr +``` + +Normally this would be sent to the Certification authority that, after verifying the author identity, returns a certificate but in this example we will use a self-signed certificate and verify the certificate. + +``` +sudo openssl x509 -req -in mosq-serv.csr -CA mosq-ca.crt -CAkey mosq-ca.key -CAcreateserial -out mosq-serv.crt -days 365 -sha256 +sudo openssl x509 -in mosq-serv.crt -noout -text +``` + +#### 5.3.3 Configuring the Broker + +Now the certificates are ready we have to configure MQTT Mosquitto Server so that it can use these certificates by editing the `mosquitto.conf` file and adding the following to the end. + +``` +listener 8883 +cafile /etc/ssl/mosq-ca.crt +certfile /etc/ssl/mosq-serv.crt +keyfile /etc/ssl/mosq-serv.key +``` + +Restarting the broker will put the changes into effect, you should see that this is now running over port 8883. If you want to connect to the broker now you will need to download the `mosq-ca.crt` certificate and use this when making connections to the broker. + +One way to download the certificate is to log out of the server and use the rsync tool to copy the file to your computer using the ssh connection. For example the following command copies the file to the `~/Documents` directory on the local workstation: + +``` +rsync -avzhe ssh root@elephant:/etc/ssl/mosq-ca.crt ~/Documents/ +``` + +### 5.4 Configuring Websockets + +The server is now configured as an MQTT broker however if you plan to use a browser to connect to it you will need to enable _MQTT over Websocket__. You will need to enable this in your `mosquitto.conf` configuration file by adding the following: + +``` +listener 9001 +protocol websockets +``` + +Rather than restarting the broker this time we will tell it to use our updated config file. Run the command: + +``` +$ mosquitto -c /etc/mosquitto/mosquitto.conf + opening websockets listen socket on port 9001 + opening ipv4 listen socket on port 8883 + opening ipv6 listen socket on port 8883 +``` + +When you restart the broker you should see that it is now running a websocket connection over port 9001 as well as the standard MQTT connection on port 8883. + +# Publish Subscribe + +Up to this point all the activities have been using the **HTTP Protocol**, which uses a _request-response_ process (the client requests a resource and the server responds with this resource). If this seems unfamiliar you should work through the HTTP Protocol worksheet. + +Whilst this approach works fine for delivering content to a web browser it is not a useful approach for certain applications. Imagine a chat room where you had to refresh the page to view new messages. + +In this worksheet you will learn how to use a new HTML5 **websocket** protocol that allows a full duplex (2 way) communication over a single TCP connection. We will then explore the **MQTT** protocol which can be run over websockets and is used to implement a _push message_ system, technically called _publish-subscribe_. + +## 1 Set Up + +Start by installing the [Mosquitto Tools](https://mosquitto.org/download). + +### 1.1 MacOS + +If you are using MacOS you should install the [Brew Package Manager](https://brew.sh) and use this to install Mosquitto using `brew install mosquitto`. + +### 1.2 Ubuntu + +If you are using Ubuntu you can install using the following commands: + +``` +sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa +sudo apt update +sudo apt install mosquitto-clients +``` + +### 1.3 Windows 10 + +If you are using Windows 10 you can download the 64 bit Binary exe and install. When you try running the commands you may need to include the **full path to the executable**. + +If (when) you encounter issues using Windows we recommend you either dual boot your computer or install [Virtual Box](https://www.virtualbox.org/wiki/Downloads) and use this to install [Ubuntu](https://www.ubuntu.com/download/desktop). There are [detailed instructions](https://askubuntu.com/questions/142549/how-to-install-ubuntu-on-virtualbox) online. + +## 2 The MQTT Protocol + +Now we have the tools installed we can start using the protocol. You have installed 2 tools, `mosquitto_pub` is used to publish messages and `mosquitto_sub` subscribes to a channel. We will use the `test.mosquitto.org` broker. + +Before connecting you will need to download the public key certificate that enables encryption between your computer and the broker. You can find this in the `exercises/MQTT` directory. Since the `mqtt.crt` file contains text this will display in the browser when selected rather than being downloaded. To solve this problem you should download the `mqtt.crt.zip` file and then unzip this to extract the key. Place this in a sensible directory on your computer such as documents. + +Nowpening _two_ terminal windows and in both of these navigate to the directory you placed the certificate file in: + +In the first window we will run the `mosquitto_sub` command and subscribe to a _topic_ called `302CEM/XXX` where `XXX` is your university username. Make sure you are running the commands in the same directory as the `mqtt.crt`. The correct password will be given out in the lab session. The topic should include your team name and your own username (replace the xxx). Note that on Windows computers you will need to include the full path to the `mosquitto_sub` command. + +```shell +$ mosquitto_sub -v -h mqtt.coventry.ac.uk -p 8883 --cafile mqtt.crt -u 302CEM -P xxx -t 302CEM/elephant/xxx +``` + +1. The `-v` is the verbose flag and this will force the program to display both the topic and message (if this is omitted it will only print the message). +2. The `-h` flag allows us to specify the _host_, in this case `test.mosquitto.org`. +3. The `-p` flag allows us to set the port (`1883` for non-secure connections and `8883` if the connection is encrypted). +4. The `--cafile` flag is where we tell the tool where the _server's public key_ is located. +5. The `-u` and `-P` flags are used to supply the username and password needed to validate the subscription. +6. The `-t` flag allows us to specify the _topic_, in this case `302CEM/elephant/XXX` (remember to substitute your team nane and username) + +The terminal will sit there, subscribed to the chosen topic, waiting to be sent some data which we will send using the second terminal window. + +In the second terminal we will run the `mosquitto_pub` command to publish messages to our topic. + +```shell +$ mosquitto_pub -h mqtt.coventry.ac.uk -p 8883 --cafile mqtt.crt -u 302CEM -P xxx -t 302CEM/elephant/xxx -m "hello world" +``` + +1. The `-m` flag allows us to specify the _message_, in this case `hello world`. + +If you look at the first terminal window (running `mosquitto_sub`) you should see your message displayed. + +The first terminal will continue to wait for messages until the command is exited by pressing ctrl+c. + +### 2.1 Test Your Understanding + +Working in small groups of between 2 and 4 people: + +1. Each member of the team should choose the same _topic name_ `302CEM/elephant`, substituting your team name. +2. Everyone runs the `mosquitto_sub` tool and subscribes to this same topic. +3. Each person launches a new terminal in a new pane (so you can see both terminal windows). +4. use the `mosquitto_pub` tool to send a message to your chosen _topic name_. +5. Look at the output of your `mosquitto_sub` command (in the first terminal window). +6. What happens if you subscribe to the `302CEM/` topic? + +What have you produced? Can you think of any application for this... + + +## References + +https://www.thepolyglotdeveloper.com/2016/06/connect-raspberry-pi-zero-usb-cable-ssh/ + +https://dzone.com/articles/mqtt-security-securing-a-mosquitto-server + +http://www.steves-internet-guide.com/mqtt-websockets/ diff --git a/03 Version Control.md b/03 Version Control.md deleted file mode 100644 index c7daf27..0000000 --- a/03 Version Control.md +++ /dev/null @@ -1,80 +0,0 @@ - -# Version Control - -In this lab you will start building your system. You will be expected to demonstrate its functionality in the first lab next week. - -Resources: - -1. [Lecture slides](https://docs.google.com/presentation/d/11ZMCBnUKRha-FxZD6NZHB0qNPZz3bFogMi952fw13FI/edit?usp=sharing) - -## 1. Planning - -There are a couple of steps you need to take before diving into the development process. These include: - -1. Deciding what feature to implement -2. Dividing the work between the team members -3. Configuring the git repositories - -### 1.1 Deciding What to Build - -Looking back at your original plans that were drawn up during the first week of labs, choose a very simple feature that you feel able to deliver in 7 days. Make sure all the team agree this can be achieved and, use paper, pens and whiteboard, analyse the task and discuss any technical issues that need to be agreed. Discuss this with the lab tutor before continuing to make sure you have not missed anything important. You should consider: - -1. What sensor you need. -2. What microcontroller will be used and why. -3. How the data will be sent wirelessly to the base station. -4. How the MCU and sensor will be powered. -5. How the base unit will receive the data. -6. How the base unit will store the data. -7. How the front-end (website/app) will access the data. -8. How the data will be displayed. -9. What security needs to be put in place. - -### 1.2 Organising the Team - -Once the plans have been agreed, the larger team should split into a number of sub-teams and the necessary work distributed between these. Make sure you are clear how the data will be moved between the teams and its format. - -### 1.3 Configuring the Repositories - -Each team will need their own repository to store any code or documentation they generate. Each team should carry out the following steps: - -1. Create a directory on the local computer. -2. Use the terminal/bash shell to navigate to this new directory. -3. Use the `git init` command to create a new repository. -4. Add a `readme.md` file and edit it to explain the purpose of thie repository. -5. Stage the changes using `git add --all`. -6. Commit the changes using `git commit -m 'initial commit'`. -7. Log into the [University GitHub repository](https://github.coventry.ac.uk/302CEM-1819JANMAY). -8. Use the **New** button to create a repository, the name should start with the name of your team! -9. Click on the **Clone or download** button and copy the repository link. -10. Add this remote using the `git remote add origin xxx` where xxx should be replaced with the link you copied. -11. Push the changes using `git push origin master`. - -Now everyone in the team should clone this repository. Complete the following: - -1. The person who created the repository should invite the rest of their subteam to become members. -2. Each person should then copy the link to the repository using the **Clone or download** button. -3. After navigating to their documents directory using terminal/bash shell ehey should clone the repository using `git clone xxx` where xxx is the link copied to the clipboard. - -Now everyone in each subteam have a copy of the appropriate repository and can start development... - -## 2 Begin Development - -Now the preliminaries have been completed you and your team need to start working. Decide quite early on: - -1. How you will communicate within the sub-team. -2. How the sub-teams will exchange key information and have discussions. -3. When the members of each sub-team will be getting together to work on the project. -4. How the work will be split between the members of the team. - -Once this is agreed, you can make a start. Remember that although you are only going to be implementing a small feature you only have a week to achieve this! - -## 3 The NSS Survey - -The [NSS survey](https://www.thestudentsurvey.com/) is a tool that the government use to rank UK universities. It is completed by all final year students and asks them to reflect on their academic journey since thay joined. The results will be used to generate the league tables that will tell employers about the relative worth of the institution and therefore the value of your degree. It is very important that you answer the questions as accurately and completely as you can. - -After clicking on the link please read carefully the information contained in the two tabs: - -1. Why take the NSS. -2. About the NSS. - -Then complete the survey. diff --git a/02 Raspberry Pi Zero W.md b/04 Building a Bluetooth Beacon.sh similarity index 100% rename from 02 Raspberry Pi Zero W.md rename to 04 Building a Bluetooth Beacon.sh diff --git a/04 Team Psychology.md b/04 Team Psychology.md deleted file mode 100644 index ca50bfc..0000000 --- a/04 Team Psychology.md +++ /dev/null @@ -1,53 +0,0 @@ - -# Team Psychology - -This week is for you and your team to take a deep breath after an intense week where you attempted to build a simple smarthome system. Despite the task seeming to be relatively simple on paper you will have struggled to get it completed. This lab you will be reflecting on why this was the case. - -Resources: - -1. [Lecture slides](https://docs.google.com/presentation/d/1_mMYilNPr1QCobs1wGp_Z6e8JyNJsOazRKAQkWbghwQ/edit?usp=sharing) - -## 1 Reflection - -Once you are all logged into the MS Teams portal you should reflect on the technical work your team carried out last week. Discuss the following points and make notes: - -1. What went well? -2. What challenges did you face? -3. What will you change next time your team works on the project? -4. Were there any skills missing from the team and how did this impact the project? - -## 2 CPD Peer Review - -During the first week you put together a document that describes three skills you have agreed to learn. Locate this document and put yourself in a small group of 2 or three away from the rest of the team. Make sure the other members of your team _don't_ have the same skill set! Print off enough copies of your CPD plan to give to the all the members of our small group (including one for yourself). - -1. Put all smartphones on silent and place them in your pockets. -2. Put all laptops in their bags and make sure any computer monitors are off. -3. Each person in the small group should go through their plan, discuss these points and make notes on the printout: - 1. Was the skill relevent to the project? - 2. Did they learn the skill? - 3. What three skills do they want to learn over the next three weeks? -4. Next, each member should create a fresh CPD plan using the headings from the week 1 lab exercise. Once complete, this document should be shared via the OneDrive folder on MS teams, you will be returning to this in 3 weeks time. - -## 3 DiSC Personality Test - -Your next task is to complete the online [DiSK personality test](https://www.123test.com/disc-personality-test/). Consider your DiSC profile, does this reflect you as a person and how you interact with the rest of the team? As a team compare your profiles and discuss how this information helps you reflect on the team interactions. - -## 4 Team Psychology - -As a group, review the materials on team psychology from the lecture: - -1. Did your group exhibit any known psychologicsl traits? -2. Why did these occur? -3. What team roles (Belbin) did members demonstrate? -4. Where on the Team Development Model (Tuckman) are you as a team? -5. By labelling these traits you should be able to search for strategies your team can employ to prevent them happening again. - -## 5 Demonstration - -The first task is to set up your system and show the lab tutor what you got working. You will be doing this even if your system is not 'complete'. If the lab supervisor is busy with another team, get the system set up and start working on task 2 while you are waiting. - -## 6 Microsoft Teams - -Next, all the group members should install MS Teams on their smartphones (and laptops if possible) and log in using their university email and password. Once logged in, everyone will find they have been placed in a team. If you are not in a team or in the wrong team, let the lab supervisor know immediately. - -Next week you will be learning about the **Scum** methodology and applying it to your development team. diff --git a/05 Scrum.md b/05 Scrum.md deleted file mode 100644 index 390e2fa..0000000 --- a/05 Scrum.md +++ /dev/null @@ -1,98 +0,0 @@ - -# Scrum - -This week you will be applying the Scrum methodology to improve the effectiveness of your team. Because you have already troubleshooted all the driver and connectivity issues, your team should be able to make some real progress this week. - -Resources: - -1. [Lecture slides](https://docs.google.com/presentation/d/1prJugx0CP3dDd5j5BqpD40mTwtzh3Ki91N2jCWagc_s/edit?usp=sharing) - -## 1 The Task - -This week your task is as follows: - -**As a home owner I want an automated lighting system so that the lights come on if there is not enough natural light.** - -This can be broken down into a number of features: - -1. The system should include an interior light and an exterior light for people approaching the front door. -2. Each light should be independently controlled. -3. The lights should not come on automatically unless the natural lighting levels are too low. -4. The threshold should be set by the user and this can differ for different lights. -5. The light should switch off if no movement is detected for 10min by default but this interval should be user definable. -6. The user should be able to override the indoor light system and switch the lights on and off using a light switch (push button). -7. The system should keep a record of when the outdoor light is triggered, to include the date/time when it switched on and off. - -## 2 Planning Poker - -Your first task for your team is to figure out the different tasks that will be needed to be completed in order to implement this feature. You should be as detailed as possible, breaking the work down into manageable chunks, writing each task on a post-it note. - -Next, one member of the team should read out the task and everyone should secretly decide how long the task will take in hours, holding up their fingers behind their backs to make their choice (with 5 fingers indicating 5 hours or more). The team should then simultaneously reveal their choices and, at this stage one of the three options below will happen: - -1. Everyone picks the same number of hours and this is 4 hours or less, write this on the note and move on to the next task. -2. Everyone picks the same number but it is over 4 hours, the team split the task into two tasks, adding these to the stack and throwing away the bigger task. -3. Members of the team pick different durations, the person with the lowest estimate explains the rationale behind their choice as does the person with the highest, then the team vote again and repeat this until they agree. - -## 3 Burndown - -Next, the total number of hours of work needed are added up and this used to produce a burndown chart. The x axis represents the amount of work (this will depend on the hours calculated) and the y axis is the number of days the team will be working (4 days, Tuesday to Friday) in this case. Calculate the necessary burn rate by dividing the total hours of work by 4. This tells the team how many task hours will need to be completed each day if the team are not to fall behind. This can be represented by a straight line from the end of the x axis to the end of the y axis as shown below. - -Here is an example of a burndown chart showing the line of optimal development. In this example the sprint lasts from Mon to Fri and there are an estimated 40 hours of development. It shows that the optimum burn rate would be 10 hours per day. - -``` - 40 ║* - ║ * - 30 ║ * - ║ * - 20 ║ * - ║ * - 10 ║ * - ║ * - 00 ║ * - ╚══════════════════════════ - M T W T F -``` - -## 4 Kanban Board - -The next step is to draw a kanban board (perhaps either on a whiteboard or flipchart paper). Use the column headings below as a guide. Now add all the tasks to the todo column as shown. - -``` -╔══════════════╦══════════════╦══════════════╦══════════════╦══════════════╗ -║ To Do ║ Plan ║ Implement ║ Test ║ Done ║ -╟──────────────╫──────────────╫──────────────╫──────────────╫──────────────╢ -║ ┌────────┐ ║ ║ ║ ║ ║ -║ │ │ ║ ║ ║ ║ ║ -║ └────────┘ ║ ║ ║ ║ ║ -║ ┌────────┐ ║ ║ ║ ║ ║ -║ │ │ ║ ║ ║ ║ ║ -║ └────────┘ ║ ║ ║ ║ ║ -║ ┌────────┐ ║ ║ ║ ║ ║ -║ │ │ ║ ║ ║ ║ ║ -║ └────────┘ ║ ║ ║ ║ ║ -║ ┌────────┐ ║ ║ ║ ║ ║ -║ │ │ ║ ║ ║ ║ ║ -║ └────────┘ ║ ║ ║ ║ ║ -╚══════════════╩══════════════╩══════════════╩══════════════╩══════════════╝ -``` - -## 5 Assign Roles - -You now need to discuss who will be taking on the role of Scrum Master and who will be the Product Owner. Refer to the lecture slides if you need reminding of their respective roles. - -## 6 Daily Stand-Up Meeting - -Now all the planning is done you are ready to start development. Stand in a huddle and make sure everyone can see both the updated burndown chart and kanban board. The Scrum Master should go around the group and ask each person in turn to answer the following three questions, taking a maximum of 90 seconds to answer all three: - -1. What task(s) have I done since the last standup meeting (are these clearly shown as complete)? -2. What am I planning on/agreeing to do before the next meeting (make sure the person writes their name on these and moves them to the **Plan** column on the board)? -3. Are there any issues that are stopping me from completing these tasks (the Scum Master should note these down)? - -Now thw meeting is over but, whilst the rest of the team are getting back to work, the Scrum Master needs to review the answers to question 3 and figure out how they can be fixed. They might at this stage consult the specialists on the team and, after putting a plan together inform the person who raised the issue explaining how it will be resolved. - - -## 7 Conducting the Sprint - -You will need to organise a daily standup meeting every morming between now and Friday. Decide on the times and how it will be conducted (face to face or video call). If you choose to use a video call make sure everyone can access it and conduct a quick group call during the lab to avoid technical issues later. - -Next week you will be expected to demonstrate working software to the lab tutor. diff --git a/06 Communication.md b/06 Communication.md deleted file mode 100644 index 27c0293..0000000 --- a/06 Communication.md +++ /dev/null @@ -1,61 +0,0 @@ - -# Communication - -This lab is to get you and your team to focus on managing your communication be effectively employing the core agile tools: - -1. The Kanban board -2. The Burndown chart -3. Daily standups - -## 1. User Stories - -The first task for the entire team is to create user stories for the features they want to include in the home automation system. These should be in the format: - -As a **ROLE** I want to be able to **PURPOSE** so that **JUSTIFICATION**. - -You should create a word document called **User Stories** under the documents tab in your MS Teams page and carefully record these. - -## 2. Team Structure - -During this lab you will be organising the team into two smaller teams of between 3 and 4 members. If you existing team is only small (up to 5) you don't need to carry out this step. - -Start by picking team names, these should be sub-species of the main team's animal, for example Tabby or Spaniel. - -To ensure both smaller teams are equally balanced, start by appointing a _scrum master_ for each team who should create a new Team in MS Teams. Let them both have access to an up to date skills competency matrix and take it in turns to pick members, making sure they have all the key positions filled. Once the teams are selected, the members of each should be added to the new Team in MS Teams. - -Each team should now pick one of the user stories to work on over the next 2 weeks, making a note in the document to show which one they have picked. From this point onwards each team will work independently. - -## 3. Daily Standup - -Since the team is much smaller, you should find it easier to find a common timeslot each day to carry out the 15 minute standup meeting (in fact with the team much smaller you might not need so long). Discuss what time suits, given you will need to meet at this time _every day_. Once this has been agreed you need to use MS Teams to set up a recurring video slot. - -## 4. Domain-Specific Language - -Now each team should take their chosen user story and create a textfile with a `.feature` extension. In this they should define the problem using the [Gherkin](https://www.tutorialspoint.com/cucumber/index.htm) DSL. This should include: - -1. The feature (user story). -2. The scenarios (functional requirements). -3. The annotations (steps to achieve each functional requirement). -4. Tags (to organise the information). - -When your small team is happy with the feature you should use a tool such as [FeatureBook](https://www.npmjs.com/package/featurebook) to build your documentation. It would be a good idea to generate a printable PDF and print copies of this ready for the next task. - -## 5. The Kanban Board - -Each team will need to create a Kanban tab in their project space, this is an instance of a **Planner** document. Create three columns as shown in the lecture slides, _To Do_, _In Progress_ and _Done_. Distribute copies of the specification (from the previous step) and work together to define a list of the small tasks needed to complete it. These should be entered as tasks directly into the _To Do_ column of the board but not assigned to anyone. - -Now each person in the team should pick a task, drag it to the middle _In Progress_ and assign it to themselves (this should not be done by the Scrum Master). As they finish a task it should be moved to the _Done_ column and checked to show it is finished. The person should then pick another task from the first column, assign it to themselves and move to the middle column. - -## 6. The Daily Standup - -Please make sure you all connect to the online standup at the appointed time. If you have the MS Teams app installed you will see the meetings in your calendar and set a reminder. Once you are connected (with camera and microphone enabled) you should each answer the following questions: - -1. What have I done since the last meeting (yesterday)? If you were unable to do anything be honest about it and give your reasons. -2. What will I aim to complete before the next meeting (tomorrow)? Again, if you can't spend any time on the project its best to be open and honest. -3. Have you encountered any problems? - -Once everyone has finished, the Scrum Master should review the progress (burndown) using the two charts in the Kanban board and let the team know whether the project is ahead or behind schedule and by how much. - -There is a recorder tool in MS Teams which will allow you to record the video meeting. You should make use of this to record a couple of the meetings and review then later to help improve your technique. - -There is a screen sharing feature in MS Teams, the Scrum Master should use this to update the team during the meetings by displaying the Kanban board and burndown/progress charts. diff --git a/07 Kanban Boards.md b/07 Kanban Boards.md deleted file mode 100644 index 1169ab8..0000000 --- a/07 Kanban Boards.md +++ /dev/null @@ -1,96 +0,0 @@ - -# Kanban Boards - -First sprint. - -### 2.1 The Kanban Board - -For this first sprint, your Kanban board should have a row for each of the user stories you have chosen to deliver and 4 columns as shown: - -``` -╔═════════╦════════════════╦════════════════╦════════════════╦════════════════╗ -║ Story ║ To Do ║ Planning ║ Implementation ║ Done ║ -╟─────────╫────────────────╫────────────────╫────────────────╫────────────────╢ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -╟─────────╫────────────────╫────────────────╫────────────────╫────────────────╢ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -╚═════════╩════════════════╩════════════════╩════════════════╩════════════════╝ -``` - -At the start of the sprint, all tasks should be in the **To Do**. By the end of the sprint, all tasks should be in the **Done** column. - -### 2.2 The Burndown Chart - -Here is an example of a burndown chart showing the line of optimal development. In this example the sprint lasts from Mon to Fri and there are an estimated 40 hours of development. It shows that the optimum burn rate would be 10 hours per day. - -``` - 40 ║* - ║ * - 30 ║ * - ║ * - 20 ║ * - ║ * - 10 ║ * - ║ * - 00 ║ * - ╚══════════════════════════ - M T W T F -``` - - -### 2.1 The Kanban Board - -For this first sprint, your Kanban board should have a row for each of the user stories you have chosen to deliver and 4 columns as shown: - -``` -╔═════════╦════════════════╦════════════════╦════════════════╦════════════════╗ -║ Story ║ To Do ║ Planning ║ Implementation ║ Done ║ -╟─────────╫────────────────╫────────────────╫────────────────╫────────────────╢ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -╟─────────╫────────────────╫────────────────╫────────────────╫────────────────╢ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -║ ║ ┌────────┐ ║ ║ ║ ║ -║ ║ │ │ ║ ║ ║ ║ -║ ║ └────────┘ ║ ║ ║ ║ -╚═════════╩════════════════╩════════════════╩════════════════╩════════════════╝ -``` - -At the start of the sprint, all tasks should be in the **To Do**. By the end of the sprint, all tasks should be in the **Done** column. - -``` -╔═══════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╦═══════════╗ -║ Story ║ To Do ║ Plan ║ Tests ║ Implement ║ Refactor ║ Regressn ║ Done ║ -╟───────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╢ -║ A ║ ┌───────┐ ║ ║ ║ ║ ║ ║ ║ -║ ║ │ a │ ║ ║ ║ ║ ║ ║ ║ -║ ║ └───────┘ ║ ║ ║ ║ ║ ║ ║ -╟───────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╢ -║ B ║ ║ ║ ║ ┌───────┐ ║ ║ ║ ║ -║ ║ ║ ║ ║ │ b │ ║ ║ ║ ║ -║ ║ ║ ║ ║ └───────┘ ║ ║ ║ ║ -╟───────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╫───────────╢ -║ C ║ ┌───────┐ ║ ║ ║ ║ ║ ║ ║ -║ ║ │ c │ ║ ║ ║ ║ ║ ║ ║ -║ ║ └───────┘ ║ ║ ║ ║ ║ ║ ║ -║ ║ ┌───────┐ ║ ║ ║ ║ ║ ║ ║ -║ ║ │ d │ ║ ║ ║ ║ ║ ║ ║ -║ ║ └───────┘ ║ ║ ║ ║ ║ ║ ║ -╚═══════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╩═══════════╝ -``` \ No newline at end of file diff --git a/08 Effective GitHub.md b/08 Effective GitHub.md deleted file mode 100644 index b5eb1b3..0000000 --- a/08 Effective GitHub.md +++ /dev/null @@ -1,2 +0,0 @@ - -# Effective GitHub \ No newline at end of file diff --git a/09 Burndown Charts.md b/09 Burndown Charts.md deleted file mode 100644 index 6d1eb78..0000000 --- a/09 Burndown Charts.md +++ /dev/null @@ -1,57 +0,0 @@ - -# Burndown Charts - -Resources: - -1. [Lecture slides](https://drive.google.com/open?id=1SS9593YC-Y38hQ1Ru9kH6mMtBAq5if656jN-Z0QISRI) - -# 1 Sprint Review - -At this stage you have completed your first sprint making use of a Kanban board. During the first lab schedule a 30min meeting with the client (lab tutor) to perform a review meeting and the planning meeting for your second sprint. - -Before this meeting: - -1. Check that the product demo will run correctly. - -During the review meeting you should follow the following steps: - -1. The product owner should discuss the user story you completed last sprint and run a demo to demonstrate ot works. -2. Let the client give you feedback and add any points raised as GitHub issues. - -# 2 Sprint Planning Meeting - -This should commence at the end of the review session. - -1. Discuss the remaining user stories in the left column of the KanBan and, working with the client decide on the updated priorities. -2. Take the top story and discuss this with the client to gain an understanding as to the detailed requirements. The product owner should ensure this is documented using diagrams and notes. It is probably easiest to produce these on paper and photo or scan afterwards. -3. All notes to be digitised and added as comments to the user story. - -Once the client has departed: - -1. Any issues raised during the review should be added to the **To do** column in the Kanban. -2. The detailed notes should be used to break the story into small tasks and added to the To do column. -3. The team should play planning poker to estimate how long each task should take: - 1. Use 1-4 fingers to indicate the number of hours. If there is a difference in estimation between the team members take a few minutes to understand why thenvote again. - 2. If you think it will take longer display all 5 fingers. This wil trigger a discussion on how it can be broken into smaller tasks. - 3. Add the agreed estimation to the task. -4. The Scrum Master adds up all the estimated durations and uses this to construct the burndown chart. - 1. You will have to agree how many days (daily standup meetings) you will need. - 2. From this you can calculate the optimal burn rate (how many of the estimated hours need to be completed each day). - -## 2.1 An Example Burndown Chart - -Here is an example of a burndown chart showing the line of optimal development. In this example the sprint lasts from Mon to Fri and there are an estimated 40 hours of development. It shows that the optimum burn rate would be 10 hours per day. - -``` - 40 ║* - ║ * - 30 ║ * - ║ * - 20 ║ * - ║ * - 10 ║ * - ║ * - 00 ║ * - ╚══════════════════════════ - M T W T F -``` \ No newline at end of file diff --git a/10 Co-Working.md b/10 Co-Working.md deleted file mode 100644 index 1f9db09..0000000 --- a/10 Co-Working.md +++ /dev/null @@ -1,51 +0,0 @@ - -# Co-Working - -In this final lab you will be applying all the skills you have learned so far but in a distributed environment. You first step should be to locate a suitable co-working space that is convenient for you to commute to, this might be: - -1. A suitable cafe near your house. -2. A cafe in the university such as the ones in the health buildings. -3. There is a co-working space on the ground floor of the the Alan Berry building. -4. There is co-working space in the council house building (The Wheelhouse). - -Now you need to discuss with the rest of your team whether you will: - -1. Start a new user story. -2. Complete a story you have already started. - -Whatever option you choose, take the time to make sure all the tasks are as small as you can manage and are added to the Kanban board. - -Now conduct your daily standup meeting with each person moving a task to the middle column, making it as _in progress_ and discussing any issues. - -Agree on what time each day you will be scheduling your daily standup and the Scrum master should create a repeating meeting schedule. Remember the absolute last day of the sprint will be next Monday (there will be no lecture). - -## Lab Support - -Both lab tutors are available via MS Teams on Tuesday and wednesday 09:00-13:00. You can request audio or video calls or message them for support. - -## Registers - -The lab tutors will be monitoring the participation of the team members. If you participate in every daily standup (we can see the logs) you will be recorded as having attended both your weekly lab sessions. - -## Recording the Demo - -Next Tuesday you will need to find time to record and edit your 3 min video demo. This will need to start with the team logo. There are lots of suitable video editors including some that can be installed on your phone. Use this list to get you started: - -- Macos / iOS: iMovie -- Windows: Movie Creator -- Linux: ShotCut -- Android: Adobe Premiere Clip - -When the video is complete and the team are happy, upload this to your team area in MS Teams. - -## Returning the Kits - -One member of each team signed for the kit at the start of the module. Once the video as been created and uploaded please dismantle the kit, check the inventory and return the kit to the lab supervisor at the start of your final lab session (Wednesday or Friday). - -## Continuing Professional Development - -Towards the end of the sprint you should review your last professional development plan and identify which of the three skill areas you have improved and how you did this. Finally reflect on your experiences and skills and identify a final list of three skill areas you feel you would like to work on before you start your first job or return on the Masters programme. - -## Uploading the Reflective Report - -The deadline for the reflective report is in May, after the Disssertation submission however you may decide the submit this early whilst things are still fresh in your mind. If you submit the report before the end of the semester you will get your final (provisional) module mark the following week. diff --git a/README.md b/README.md index 4a3d4c8..fe8c712 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,4 @@ -# Agile Development +# Raspberry Pi Resources -Welcome to the final year **Agile Development** module. This will teach you the skills you need to work in a modern software development team. Along the way you will gain lots of experience in developing a software solution. - -## Learning Outcomes - -On completion of this module the student should be able to: - -1. Demonstrate a sound understanding of how Agile Methodologies can be used to define users’ requirements, analysis and design of information systems. -2. Compare and contrast a range of current and emerging agile methodologies -3. Evaluate the methods, techniques and tools for rapid development of various types of information systems, and the reasons for their selection and use. -4. Use a range of appropriate tools to contribute to the development of a solution to a real-world problem. - -## Teaching Materials - -The teaching materials are broken into 10 labs split into 3 parts. Each week you will be provided with a labsheet that explains exactly what you will need to complete and containing a link to the appropriate presentation. - -1. the first two weeks cover the technical skills you will need to complete the module and the labs are to be completed individually. -2. Weeks 3-4 prepare you for the agile development. -3. Weeks 5-10 are where you complete the sprints and develop the software. - -## Assessment - -Link to the assignment. -Link to the grading rubric. - -## Module Overview - -During this module you will be working in medium-sized multi-skilled development teams on a real problem. The content of the module is as follows: - -1. Programming refresher with TDD. - 1. NodeJS and C++ -2. Skills - 1. MQTT etc. -3. Team Building (Professional development) - 1. form teams - 2. skills audit -4. Problem Domain Modelling (UML) - 1. Requirements gathering and domain mapping. - 2. User stories. -5. Sprint 0 - 1. Architecture. - 2. Data storage. -6. sprint 1: - 1. Effective use of git - 2. fixed story: broadcast MQTT lat lon. -7. Sprint 2 - 1. Kanban board (electronic). -8. Sprint 3 - 1. Effective use of GitHub Issues -9. Sprint 4 - 1. Burndown charts -10. Sprint 5 - 1. User story mapping -11. Exam revision +This repository contains a range of resources to help you build and configure your Raspberry Pi to carry out a wide range of tasks. \ No newline at end of file diff --git a/exercises/.images/etcher_software.png b/exercises/.images/etcher_software.png new file mode 100644 index 0000000000000000000000000000000000000000..6999a03a98ea7a970ad52c9ea1149e088251b9ce GIT binary patch literal 94724 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⁡XH=hU;l5o;DxZ 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 literal 0 HcmV?d00001 diff --git a/exercises/.images/raspbian_buster.png b/exercises/.images/raspbian_buster.png new file mode 100644 index 0000000000000000000000000000000000000000..b69385ad9836f6bcba926eedab63d93dab9b8ca5 GIT binary patch literal 39137 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 SJjuR?K9uCtWlLqu0{;U+>NNHM literal 0 HcmV?d00001 diff --git a/exercises/.images/raspi-config_tool.png b/exercises/.images/raspi-config_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..0732c3fddadfa47cf3c4e1391449ad5723049f28 GIT binary patch literal 44472 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[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 DJTIg6 literal 0 HcmV?d00001 diff --git a/projects.md b/projects.md deleted file mode 100644 index 1027348..0000000 --- a/projects.md +++ /dev/null @@ -1,12 +0,0 @@ - -# Projects - -This document contains resources for the module projects. - -## Robotic Sailing Boats - -[Making your boat go faster](http://radiosail.com.au/wp-content/uploads/2012/08/Making-Your-RC-Laser-Go-Faster.pdf) - -[UK Radio Controlled Laser Association Website](http://www.rclaser.org.uk/) - -[Braid Upgrade Instructions](http://www.abersochboatyardservices.co.uk/RC%20Laser%20Braid%20Instructions.php)