/ fridayfun

Friday Fun Revisited: Pollen Checker v2

alt
So a couple of weeks ago I wrote three simple scripts to get the current pollen data at your location. And for 90% of the readers it worked well.

But?

Well there was an issue with using GeoIP (getting our location based on our IP address.) It worked well for most people, only off by about half a mile max, but for some it showed their position as many miles away. My friend Simon who lives in Chorley, Lancashire, reported that his location was being shown as Cleveleys, around 40 miles away. So I needed to address this.

How did you find the answer?

Short answer...Google. Longer answer it was via working with Joe Luzzi on a Twitter weather bot project that I discovered GeoPy and it seemed to fulfill my needs for the Pollen Checker project...so I did a test and it worked!

How to install GeoPy

GeoPy is available via pip, so open a terminal in Linux and type

sudo pip3 install geopy

For Windows users, open a Command Prompt and type

pip3.exe install geopy

Where can I find the old and new code?

Of course the code is online via GitHub and you can download it and hack around!

The original project: Showing a popup on the Linux desktop

alt
The original code is in the top right window, and the new code in the bottom left

Lets make the code better!

So starting with the imports, you will see that json and requests are gone, replaced with geopy.geocoders from the GeoPy library.

import os
from pypollen import Pollen
import notify2
import time
from geopy.geocoders import Nominatim

Then we create an object that will use the Nominatim search function for Open Street Map, it will enable us to search for a location based on part of an address.

geolocator = Nominatim()

The images section of the code stays the same, so we get the pretty flowers coloured to denote the pollen level.

cwd = os.getcwd()
VeryHigh = cwd+"/Images/VeryHighPollen.png"
High = cwd+"/Images/HighPollen.png"
Moderate = cwd+"/Images/ModeratePollen.png"
Low = cwd+"/Images/LowPollen.png"

Next up we start the loop, and then create an object called location that will store the Geolocator data we get for the location that we wish to use for our pollen count. In this case I used Blackpool as a very general location. But you can supply street addresses and post/zip codes.

while True:
    location = geolocator.geocode("Blackpool")

Rather than faff for the longitude/latitude data from dictionairies like we did in V1 of the script, we can call the location object and ask it to supply the latitude and longitude data (supplied as floats.)

    lat = location.latitude
    lon = location.longitude

The rest of the code is as per V1.

    pollen_status = Pollen(lat, lon).pollencount
    notify2.init("Pollen Count Data")
    if pollen_status == "Very High":
        n = notify2.Notification("The pollen level at your location is ",pollen_status,icon=VeryHigh)
        n.show()
    elif pollen_status == "High":
        n = notify2.Notification("The pollen level at your location is ",pollen_status,icon=High)
        n.show()
    elif pollen_status == "Moderate":
        n = notify2.Notification("The pollen level at your location is ",pollen_status,icon=Moderate)
        n.show()
    elif pollen_status == "Low":
        n = notify2.Notification("The pollen level at your location is ",pollen_status,icon=Low)
        n.show()
    time.sleep(15)

Save the code and give it a test!

The other projects

I've also changed the code for V2 of the Blinkt LED board and the Windows project. So you are free to use V2 of those projects too!

Come on Les it's Friday and I need something cool to do!

Sheesh! Ok lets have the pollen count data read to us by Google!

So the first thing we need to do is install some extra software.

Linux / Raspberry Pi Users

Open a terminal and install mpg123, we will use that to "speak" the audio.

sudo apt install mpg123

Now using pip install the gTTS (Google Text To Speech) engine.

sudo pip3 install gtts

Windows Users

Download a command prompt MP3 / audio player from Jim Lawless' Blog and extract the file called cmdmp3.exe and save this in the same directory / folder as where you will save your code!

Now open a Command Prompt and install gTTS (Google Text To Speech) engine using pip.

pip3.exe install gtts

Open your favourite Python editor and start writing the code.

Imports

We import the same libraries as in V2 of the code (using the GeoPy library is sooo much easier!) But we also import gTTS.

import os
from pypollen import Pollen
import time
from geopy.geocoders import Nominatim
from gtts import gTTS

Then we create an object to use the Open Street Map search tool.

geolocator = Nominatim()

Then we find out the directory where the code is running.

cwd = os.getcwd()

In a loop we get our location data, just as in V2 of the original code. Then extract the latitude and longitude data, and use it to get the pollen count for our location.

while True:
    location = geolocator.geocode("Blackpool")
    lat = location.latitude
    lon = location.longitude
    pollen_status = Pollen(lat, lon).pollencount

Next we have a new line of code that creates a variable called text and in there we store the text that will be read out by Google.

    text = "The pollen level at your location is "+pollen_status

So how does Google speak the text? Well really it doesn't! What happens is that the text in our variable is processed by Google's text to speech engine and an MP3 file is created. The MP3 is then saved into the same location as where the code is run (and for Windows users the same location as the cmdmp3.exe file.)

    speech = (gTTS(text=text))
    speech.save(cwd+"/speech.mp3")

Ok we are nearly there! This next step creates a path (the location) to the command that will play the audio (Linux users this is mpg123, Windows users change it to cmdmp3.exe) and then the speech.mp3 file containing the audio.

    speech_path = "mpg321 "+cwd+"/speech.mp3"

So now lets have the computer tell us the pollen count for our location. For this we use the os.system function to call the variable speech_path which contains the command to play the audio, and the audio to play.

    os.system(speech_path)

The last thing we do is create a delay using time.sleep() and for the test version I set this to 15 seconds. Please test with this value, but when using it for real, change it something sensible.

    time.sleep(15)

Save the code and then run it! Listen as the cool, disembodied robotic voice tells you the pollen levels in your area.