In this documentation, we outline the requirements for installation, setup, and management of a wirelessly connected N Raspberry Pi bramble.
- Raspberry Pis will require some usage of the Linux terminal and it's worth knowing how to get around a bit. The Raspberry Pi foundation provides a quick tutorial
- As great as it is, it does not give you information on how to use
nanothe default Linux text editor: - Many of the Raspberry Pi camera commands can be better used with the Python library included with Raspbian. The Raspberry Pi foundation also provides a quick python tutorial
- Feel free to refer back to these links as you go through the installation steps for the Raspberry Pi
- Also, when instructions are surrounded in brackets
<>such as<YourInputHere>type your particular name or folder name there without the brackets - You will also need an introduction to GitHub to clone and use this repository
- GitHub primer to get you started: GitHub Introduction: Hello World!
- To clone this GitHub repository:
- Type or copy/paste:
git clone git@github.com:calizarr/EPSCoR_Bramble_GH9C.gitto clone this repository into a folder named EPSCoR_Bramble_GH9C - If you want to clone it into a different folder name, type:
git clone git@github.com:calizarr/EPSCoR_Bramble_GH9C.git <YourFolderName>
- Type or copy/paste:
- N number of Raspberry Pis (rPIs)
- Each rPI should have a camera module and a WiFi dongle
- We use the WiPi Dongle
- Allows transmit power changes without reboot
- More powerful than Adafruit dongles
- Each rPI should have its own case
- Centralized Linux server/desktop to run Ansible
- Networked and able to connect to t0he rPIs
- Must be on 24/7
- Must have enough storage space to store images
- Ansible Requirements
- Depending on the setup of the centralized server that will be launching Ansible, you will need to pick what is best for you from the Ansible installation documentation
- We installed Ansible from github for a rootless (no privileges) installation
- If installed on a server infrastructure, and you do not have access to an administrator or administrator privileges, a github installation may be the best option for you
- Ansible setup is rather straightforward and should not be very problematic
- After you have installed Ansible on your server, make sure to generate ssh keys for the server
- GitHub Generating SSH-Key
- Digital Ocean SSH Key Tutorial
- Don't disable password for root login
- Raspberry PI Quick Start Guide
- First, we need to install an operating system onto the Original Raspberry Pi sd card
- Follow this documentation: Raspberry Pi Installing Operating Systems
- Debian jessie is the recommmended raspbian distribution
- To avoid problems in the future, make sure that your SD card used for cloning is the smallest SD card you have. Even if they claim to be of the same size -- 8 GBs is not the same across all SD cards.
- Follow all the prompts after installing Raspbian/Debian Jessie onto the Original Raspberry Pi, then continue onward
- Log in to the Original Raspberry PI using a usb mouse and keyboard and an HDMI-capable monitor
- WiFi:
- Set up the network following instructions using the Graphical User Interface (GUI): GUI WiFi Setup
- Look only under the New Wifi Interface heading
- If using the command line interface (CLI), follow this set of instructions: Raspberry PI CLI setup
- Set up the network following instructions using the Graphical User Interface (GUI): GUI WiFi Setup
- Camera:
- Hostname:
- Change hostname using command line
- Make sure to give your Raspberry PI a unique hostname
- Our rPIs hostnames range from ShakoorCamera11 to ShakoorCamera190 so that they do not conflict with each other
- We also gave our rPIs static IP addresses ranging from 10.9.0.11 to 10.9.0.190
- Given the density of our bramble we had to provide static IP addresses, but it may not be necessary otherwise
- Static IP Addresses are a bit more complicated but they are documented here
- The previous GUI WiFi Setup also includes information on how to set up static IP addresses via the GUI
- Also take a look at the file in pi_config/dhcpcd.conf for an idea of what to put in your dhcpcd.conf
- Most of it is default boilerplate, the important section for static IP addresses starts at line 43
- Your
domain_name_servers,ip_address,routers, andhostnamewill be different
- Wireless Power Management:
- Open a terminal:
- Type or copy/paste:
sudo nano /etc/network/interfacesin a new line underwlan0 - Type or copy/paste:
wireless-power off - Exit and save the file with nano. (
Ctrl+X -> Y -> Enter) - This removes all wireless power management which prevents random disconnects
- Type or copy/paste:
- Open a terminal:
- OpenSSH Server
- Open a terminal and type or copy/paste:
sudo apt-get install openssh-server - Test the ssh server by logging in with:
ssh pi@localhost - To also test if your hostname works check:
ssh pi@<YourHostnameHere> - Finally, if hostname doesn't work, find your Raspberry Pi IP address and try:
ssh pi@<YourIpAddressHere>- If hostnames don't work, I highly suggest setting up static IP addresses for each rPI to make sure that you know which one you are accessing
- To make sure all rPIs have the Ansible server's ssh-key and are a known host, from the Ansible server:
- Open a terminal and type or copy/paste:
ssh-copy-id pi@<YourHostnameHere>orssh-copy-id pi@<YourIpAddressHere> - If you don't do this step you will have to copy it individually for every rPI you have later!
- Open a terminal and type or copy/paste:
- Open a terminal and type or copy/paste:
- Set the Timezone
- Open a terminal and type or copy/paste:
sudo dpkg-reconfigure tzdata - Set your timezone
- This will be the timezone of all the rPIs in the bramble
- If you don't do this step you will have to copy it individually for every rPI you have later or use UTC time!
- Open a terminal and type or copy/paste:
- Playbooks Adjustments
- If you will be using the playbooks in this repository, then you need to add a few things on the original rPI
- Make a folder for the images:
- Open a terminal and type or copy/paste:
mkdir /home/pi/Images
- Open a terminal and type or copy/paste:
- Alter the python camera script to suit your needs
- Comment out lines 143-144 and uncomment line 145
- Lines 143-144 look like:
grid = convert_ip(get_ip(), width, height, offset)
filename = "{hostname}_Y{y}_X{x}_{now}.png".format(hostname=hostname, x=grid[1], y=grid[0], now=now.strftime("%Y-%m-%d-%H-%M")) - Line 145 looks like:
# filename = hostname+"_"+now.strftime("%Y-%m-%d-%H-%M")+".png" - If you have GPS info for each rPI, add a
gps_info.txtto the home directory.- There is a GPS section in the camera script. The file should have the proper values in this manner:
GPSLatitudeRef; GPSLatitude; GPSLongitudeRef; GPSLongitude; GPSAltitudeRef; GPSAltitudeRef; GPSMeasureModeN; 38674226/1000000,0/1,0/1; W; 90397316/1000000,0/1,0/1; 0; 604/1; 2
- After altering the script, copy the python camera script to
/home/pi/- You can do it by copying the python camera script to the
/home/pi/folder in the Raspberry Pi - You could also clone the repository onto the Original Raspberry Pi, alter the script, and then move it to
/home/piby opening a terminal then type or copy/pastemv camera_single.py /home/pi
- You can do it by copying the python camera script to the
- Before cloning make sure you have followed the necessary Raspberry Pi setup steps above.
- After setting up the first Raspberry Pi, you will want to clone the image and copy it onto all your other Raspberry PI SD Cards
- Follow any of these guides to backup then restore (clone) your Raspberry PI Image
- In general, backup the image then use that image to restore it onto all the other SD cards. You can use Win32DiskImager on Windows or the
ddtool in Linux
- After restoring/cloning the image onto each SD card, make sure to change its hostname to be unique. You can do this two ways with either a Linux or Apple machine or a Raspberry Pi connected to monitor and keyboard:
- Navigate to the folder where the SD card is mounted,
/mediafor Linux and/Volumesfor Apple- Follow the instructions in the hostname section above
- Ignore the section with
sudo /etc/init.d/hostname.shsince the sd card isn't booted up into the operating system at the moment and when it gets put into a rPI and is powered on is essentially the same
- Put the SD card into a rPI connected to a monitor, keyboard, and mouse and follow the hostname change section above
- Navigate to the folder where the SD card is mounted,
- The hostname change section has to be done for each and every SD card that will be placed in a different Raspberry Pi!
- You can now start to manage your Bramble with Ansible on the centralized server
- Lets start by making a hosts file also known as the Ansible Inventory
- A sample hosts file from our configuration is here: hosts
- All our rPIs are referred to by their IP address, but they don't need to be if your network identifies them by hostname
- If you could previously connect via ssh by hostname, you don't need ip addresses. You could also
ping <HostnameOfRaspberryPi>to test
- Use it as a guide, but almost everything in the hosts file must be different and specific to your setup
- I find it useful to define a group with localhost (the server) for use in playbooks. In our hosts file, it is the
clizarraga_chronosgroup
- A sample hosts file from our configuration is here: hosts
- If you need to use proxy settings or specific ssh settings, then you need to edit the Ansible configuration file
- A sample configuration file is here: config
- Default configuration file from Ansible.
- Most of the changes are for ssh options because of connectivity and interference issues. Head to the playbooks folder readme for more information
- So, you've setup your Raspberry PIs and you have installed and set up Ansible with your own hosts and configuration file
- You should test your Ansible install by running
ansible -m ping allfrom a terminal on the Ansible server
- You should test your Ansible install by running
- This repository contains a playbooks folder with playbooks made to manage the Raspberry Pis via the centralized server
- Before changing any playbooks, please read the Ansible playbooks documentation
- The playbooks have a lot of assumptions built into them:
- All images taken on the rPI use camera_single.py
- All images on the rPI are stored in
/home/pi/Images/
- Playbooks
- For all playbooks:
gather_factsdoesn't need to be false if you don't have connectivity issueswhen:determines when a task will run if the variable after it is false, it will not runbecome:determines if the task will be run as a superuserhosts:needs to be changed to your appropriate inventory group
- copy-pictures.yml -- Needs to change to be specific to the user setup
- Variables
img_dirandlocal_dirneed to be changedimg_dirneeds to be changed only if you're not using/home/pi/Imageson the rPIs as your image destinationlocal_dirneeds to be changed to where the image files will be stored on the centralized server- Task:
Pull with rsh/ssh and rsync from chronos- Pulls images from the rPIs and removes them once transferred to the Ansible server location
- Options:
remove-source-filesremoves the files from the rPI once transfer is successfultimeouttimes out the operation after N seconds
- More information on rsync options is available via
man rsync
- Variables
- sudo-plays.yml -- Contains true/false variables that need to be changed depending on context
- The tasks containing
utmp,sshd, orDNSare for connectivity issues- In general, its best to leave them false
- Timezone task(s):
- Change the
timezone_changevariable and change thetimezonevariable itself to your desired timezone - Use one of the strings from the TZ column in this list of TZ database timezones
- Change the
- Task:
Add hourly cron job from 5 AM to 9 PM- Currently it takes images every hour between 5 AM (5) and 9 PM (21)
- To understand more about cron, read
man cronand the Ansible cron module
- Task:
Send camera_single.py to the rPIs- Change
src:to the absolute path ofcamera_single.pyon your Ansible server
- Change
- GPS tasks(s):
- Task to use
master_gps.txtcoordinate file to setgps_info.txtin the home directory of every rPI. - An example file is included in the repo.
- Task to use
- There is a secondary playbook in the file aimed at the localhost (
clizarraga_chronos) to set up a cron job on it- Change the
hosts:to your localhost designation in your hosts/inventory file - Change the
jobs="cd <YourPlaybooksDirectoryHere> && time bash -x playbook-ansible.sh -i <YourHostsFileHere> -vv- The
-f 2option forces Ansible to do only two at a time instead of its usual 5. You can also set it to more processes at once if you want
- The
- Change the
- The tasks containing
- wireless-power.yml -- Sends the interfaces file to the rPIs
- Change the
src:to the absolute path of theinterfacesfile on your Ansible server
- Change the
- take-pictures.yml -- Sends command to the hosts to call
camera_single.py
- For all playbooks:
- Playbook-Ansible Bash Script
- The playbook-ansible.sh script needs two major things:
- If Ansible is installed via the package manager
- Comment out line 2 of the script
source /home/clizarraga/usr/local/ansible/hacking/env-setup
- Uncomment line 3 of the script
# ansible-playbook=/usr/bin/ansible-playbook
- Comment out line 2 of the script
- Otherwise, if you used the github installation mechanism:
- Replace
/home/clizarraga/usr/local/ansible/hacking/env-setupwith the<path/to/ansible>/hacking/env-setup
- Replace
- The script uses a
logsdirectory to store logs named by playbook andyear-month-date. Make sure there is a logs directory in the path that the script is in. You can make one by runningmkdir logsin the path to the bash script
- If Ansible is installed via the package manager
- The playbook-ansible.sh script needs two major things:
- You can manage the bramble via Ansible with more playbooks that you can create yourself using the documentation provided above. You can also use the playbooks as a template for future playbooks
- A good way to test some Ansible commands beforehand is to use Ansible modules with ad-hoc commands
ansible -m ping alloransible -m command -a lsare good examples
- If you need to transfer files from an rPI to the Ansible server or vice versa you can use:


