Previously in I've set out the objectives and environments for PyBloom. Now in part 4, I look at how to organise the code and pre-requisites.
Organising the code
The code should follow the technical stories described previously, but the mapping of module to story isn’t straightforward.
Mapping stories to modules
Let’s get onto the actual writing.
Prerequisites
Like all Python programs, my code builds upon libraries written by other people.
The code
Each weather reading is called an observation. The weather_observation class is responsible for fetching the current weather observation, for and for logging. Let’s get into it, starting with the third party libraries that I use.
from datetime import datetime, timedelta
Dates and times are funny to manage. Thankfully, both Python and SQLite have datetime modules that handle the complexity, simplifying the representation of the maths.
import qhue
Qhue provides a python wrapper for the Philips API, making it much more straightforward to access the lights as Python resources.
from rgbxy import Converter
from rgbxy import GamutA
Philips Hue light colours are complicated. They use (x,y) coordinates that describe a point in a colour space. CSS, the technology that describes the presentation of web sites, uses the RGB representation of colour. Thankfully, this library converts between the two, and even makes sure that the bulbs are able to show the colours (are within the bulb’s gamut).
import pyowm
Another wrapper, pyOWM provides a python wrapper for the OpenWeatherMap API. It provides a weather manager object that handles all the API complexity, and presents as a Python resource. The free version of the API has a limit of the number of calls allowed per month. To make sure I’m under this limit, the code writes each observation into a persistent database which can then be queried as many times as I like.
import sqlite3
To make the measurement data (and other data) persistent, it’s written into a database that can be accessed by other code objects such as the web page. Whilst there are many database technologies, I went with SQLite as it’s built into Python, so no need to download any more libraries.
import pygal
I’ve used powerful visualisation libraries like MatPlotLib and Seaborn, and they’re complicated because they’re powerful. By contrast, I found Pygal to be super easy.
from db_setup import db_connect, get_rows
I wrote my own helper utilities to make connecting to, fetching data from, then shutting the connection to my SQLite database a little easier. Whilst there are other approaches like decorator functions to do this, a utility made more sense to me. More on this when we look at the code.
Here now are the global constants:
DATETIME_STRING = '%Y-%m-%d %H:%M:%S'
FILEPATH = './app/static/'
We’re going to need these two constants later on in the code, but because they’re trivial to understand, let’s introduce them now. The first governs how the datetime function mentioned earlier works in both Python and SQLite. More on the reason for the syntax in the section on logging.
The second constant is the file path for the web site assets. More on the reason for this file path in the section on presenting in a web page.
OWM_KEY = credentials.credentials['owm_key']
HUE_USERNAME = credentials.credentials['hue_username']
HUE_IP = credentials.credentials['hue_ip']
HOME_LOCATION = credentials.credentials['home_location']
These global constants are the secrets used by the APIs to secure the calls. You’ll need to note your own in a credentials.py file, as we’ll see in a future section.
Putting it together
from datetime import datetime, timedelta
import qhue
import pyowm
from rgbxy import Converter
from rgbxy import GamutA
import sqlite3
import pygal
from db_setup import db_connect, get_rows
DATETIME_STRING = '%Y-%m-%d %H:%M:%S'
FILEPATH = './app/static/'
OWM_KEY = credentials.credentials['owm_key']
HUE_USERNAME = credentials.credentials['hue_username']
HUE_IP = credentials.credentials['hue_ip']
HOME_LOCATION = credentials.credentials['home_location']
No comments:
Post a Comment
It's always great to hear what you think. Please leave a comment, and start a conversation!