Sunday 17 June 2018

Pi Camera stop motion animation

In preparation for a Raspberry Pi event I decided to create a simple GUI for creating stop motion animations using the Pi camera module to use for a demo.


Its a really simple application, you start it up, you click "take image", you re-position the scene, you click "take image" and so on until you are happy with your animation and you click "save" to store it as an animated gif.



You can find the source code at goo.gl/4Xvu7b.

Install
1. Connect a camera module
2. Enable the camera (Menu > Preferences > Raspberry Pi Configuration, Interfaces, Camera)
3. Open a terminal (Menu > Accessories > Terminal), install the modules and download the code:
sudo pip3 install guizero
sudo pip3 install imageio
wget -O guizero_stopmotion.py https://goo.gl/zMTjas
4. Run the program:
python3 guizero_stopmotion.py

A couple of "interesting" things about this project

The gui was created using guizero which is a super simple to use library for creating GUI's, definitely have a look.

Most of the work was finding a way to create animated gifs in Python and working with images in memory rather than stored on disk

When the image is captured from the camera it isn't stored to a file, it is stored in a numpy array, this means each frame is only stored in memory making it faster:
# create the camera
camera = PiCamera(resolution="640x480")
camera_output = PiRGBArray(camera)
...
# capture the image
camera.capture(camera_output, "rgb")
# append the camera image to the list as a numpy array
animation.images.append(camera_output.array)
The python module imageio is used to create the gif by passing the frames as a list, but again rather than being written to disk each time it is created as an in memory BytesIO stream:
gif_output = BytesIO()
imageio.mimsave(gif_output, animation.images, format="gif")
When the animated gif is displayed in guizero the BytesIO stream has to be open into a PIL Image.
animation.image = Image.open(gif_output)


Saturday 9 June 2018

Get the weather using Python

I recently spent a hour or so hacking a lucky cat so that it would only wave when it was sunny.
It did this by pulling the weather data from Open Weather Map using the Python module pyowm.

1. Sign up for a free API key in Open Weather Map.

2. Install the pyown Python module, open a Terminal or Command Prompt and run:

Windows
pip install pyown

Raspberry Pi / Linux
sudo pip3 install pyown

MacOS
pip3 install pyown

3. Create a Python program using the following code, inserting your API key:
import pyowm

owm = pyowm.OWM('put api key here')

observation = owm.weather_at_place('Cambridge,GB')
w = observation.get_weather()

clouds = w.get_clouds()
wind = w.get_wind()
humidity = w.get_humidity()
temp = w.get_temperature('celsius')

print("{}, {}, {}, {}".format(clouds, wind, humidity, temp)

Note - it can take up to 60 minutes for your API key to be activated.

There is a lot more information which can be pulled back - have a look at the weather module documentation for more details.


Sunday 4 March 2018

Python - Creating shortcuts

I was recently working on the mu project (a Python IDE for beginners), which is super easy to install using pip, but there is no way to automate the creation of desktop and menu shortcuts.

This seemed like a really big miss, shortcuts are the usual way for people (and certainly beginners to launch applications).

So I set to creating a really simple way of creating shortcuts for Python applications.

Enter shortcut, a X platform (Windows, MacOS, Linux, Raspberry Pi) Python module for automatically creating shortcuts.

Its really simple to install and use:
pip3 install shortcut
shortcut name_of_app
It will find the location of the app and create desktop and menu shortcuts for it.

There is also a Python API which can be used to do the same:
from shortcut import ShortCutter
s = ShortCutter()
s.create_desktop_shortcut("python")
s.create_menu_shortcut("python")
You will find documentation at shortcut.readthedocs.io and code at github.com/martinohanlon/shortcut.

Friday 29 December 2017

Setup Raspberry Pi Samba share

I almost always setup a samba share on every Raspberry Pi I install, it allows me to easily share files and work on my projects - so I thought I had better write down how I do it.
Install samba:
sudo apt-get install samba
Modify the Samba config file to add a share called pihome which points to the /home/pi directory:
sudo nano /etc/samba/smb.conf
Scroll to the bottom and add the following:

protocol = SMB2

[pihome]
   comment= Pi Home
   path=/home/pi
   browseable=Yes
   writeable=Yes
   only guest=no
   create mask=0644
   directory mask=0755
   public=no

Setup a samba password for the Pi user:
sudo smbpasswd -a pi
Restart the samba service:
sudo service smbd restart
You should now be able to connect to your Pi using the address:
//ip_address_of_pi/pihome

Wednesday 15 November 2017

Slack command line stream

I thought a Slack console might be useful, a very simple client I could display on an always on screen, so I did some experimenting with the Slack Developer Kit for Python and made a super simple command line program which streams messages.

It is most definitely a starting point rather than a finished solution, but someone might find it useful.


Setup (assuming you are using a Raspberry Pi / Linux computer, although it will work on Windows as well).

1. Generate a security token for the slack group you want to stream.

2. Create an environment variable SLACK_API_TOKEN and put your security token in it.

Edit /etc/profile adding the export to the bottom:
sudo nano /etc/profile
export SLACK_API_TOKEN=[my super long token]
3. Install slackclient and colorama using pip:
sudo pip3 install colorama
sudo pip3 install slackclient
4. Download the slack_stream.py from gist:
wget https://gist.githubusercontent.com/martinohanlon/477b6ea4c3bdc679ddff92dfc3bff4a7/raw/8ec39d08a9501b25d381ac3b008e9cf7be92377a/slack_streamer.py
5. Run it:
python3 slack_streamer.py

Friday 7 July 2017

Python Bluetooth RFCOMM Client Server

As part of the Blue Dot project I needed to create a simple Bluetooth client / server library so that the communication could be managed. This library, btcomm, is part of bluedot but its not exclusive and can be used for Bluetooth communication in Python.

It uses a 2 way RFCOMM communication - you can send messages to and from 2 devices, 1 being the server which waits for connections, 1 being the client which makes a connection.

Install the library
sudo apt-get install python3-dbus
sudo pip3 install bluedot

Pairing

The 2 devices you which want to communicate between will need to be paired, the Blue Dot documentation describes how to pair 2 raspberry pi's which might be useful.

Simple Client / Server Example
Lets create a simple example, a server which waits for connections and when it receives data it echo's it back to the client.

Create a new Python program and save it as btserver.py:

from bluedot.btcomm import BluetoothServer
from signal import pause

def data_received(data):
    print(data)
    s.send(data)

s = BluetoothServer(data_received)
pause()

Create a 2nd program and save it as btclient.py:
from bluedot.btcomm import BluetoothClient
from signal import pause

def data_received(data):
    print(data)

c = BluetoothClient("nameofyourserver", data_received)
c.send("helloworld")

pause()

Run the server and then run the client, the client should connect and "Hello World" will be sent to the server and displayed on the screen, the server will then send the same "Hello World" message back to the client, which will print it to the screen.

Adapter

There is also a useful API for accessing the Bluetooth adapter allowing you to get its current status, power it on/off, make it discoverable or find the devices its paired with.
from bluedot.btcomm import BluetoothAdapter

a = BluetoothAdapter()

print("Powered = {}".format(a.powered))
print(a.paired_devices)
a.allow_pairing()

Documentation

There is comprehensive documentation for the btcomm library, which describes the API and how to use it.


Tuesday 4 July 2017

Mac OS - Check Java version before running script

I needed to check what version of Java was installed on a Mac before running my program, so with the help of stackoverflow and a few other resources I pulled together the following bash script which checks to see if the version of Java is greater than 1.8 before continuing.
# Work out the JAVA version we are working with:
JAVA_VER_MAJOR=""
JAVA_VER_MINOR=""
JAVA_VER_BUILD=""

# Based on: http://stackoverflow.com/a/32026447
for token in $(java -version 2>&1 | grep -i version)
do
    if [[ $token =~ \"([[:digit:]])\.([[:digit:]])\.(.*)\" ]]
    then
        JAVA_VER_MAJOR=${BASH_REMATCH[1]}
        JAVA_VER_MINOR=${BASH_REMATCH[2]}
        JAVA_VER_BUILD=${BASH_REMATCH[3]}
        break
    fi
done

#check version is greater than 1.7 (i.e. at least 1.8)
if [ "$JAVA_VER_MAJOR" -gt "1" ]; then
    echo start your program
elif [ "$JAVA_VER_MINOR" -gt "7" ]; then
    echo start your program
else
    echo ERROR - Java needs to be updated.
    echo Currently installed version is $JAVA_VER_MAJOR.$JAVA_VER_MINOR - 1.8 is required
fi