Part 1: Objectives
As is the case with many complicated things in life, this project started with a simple objective statement:
“Replace the temperature to lights feature currently implemented in IFTTT paid-for, into a free method.”
It turns out that there’s a bit to unpack from this statement in order to develop the requirements to build against. Let’s get into the detail:
“Currently implemented in IFTTT paid-for”: IFTT is going pro = no longer free. It’s not worth a monthly fee to me, for the value it delivers to my IoT home.
“Into a free method”: There are plenty of web-hosted services that are free, or have a free tier. Moreover, the Philips Hue service is actually hosted in my own home, so will never have a fee. My challenge is therefore to build something that is free.
Use services within their free tier
Use devices that I have lying around the house
“Temperature to lights feature”: Put simply, the feature that I built in IFTTT changes the colour of a Hue Bloom in my lounge in response to a temperature change. If the temperature goes above or below a certain threshold, the bloom light changes. I can then tell the temperature just by looking at the colour of the light.
Map outside temperature forecast to a colour
Show this colour in the Bloom
Because this isn’t hard enough, my wife suggested a couple of stretch targets:
Graphically represent the temperature information
Maintain graphs of historical temperature information
Present in a way that is easy to access
Match the colours in the graphs to the colours in the Bloom
Technical Stories
Let’s refactor these objectives into technical stories that I can build against.
Non-functional requirements
Be free.
I settled on using the following technologies:
Open Weather Map API free tier
My Mac Mini as a development environment
An old first generation Raspberry Pi to be my always-on production environment
Main development language of Python (v3.7 in prod, v3.8 in dev)
Atom as my IDE
Flask as the web page building framework
Bootstrap as the CSS framework
Story: Check current weather
Create a weather observation class object:
Initialisation function to call weather API to get current weather
Representation string to give last called time
Accessor for current temperature
Story: Assign colour depending on temperature
Dictionary of temperature boundaries and colour if greater than
Story: Change colour of Philips Hue Bloom to display temperature
Create a lounge bloom class object:
Representation string to give current colour
Accessor to set current colour
Story: Log the weather reading
Append new observation into SQL database
Story: Make Hue colours available from external SQL database
Build SQL database in setup script
Create lookup function to query db
Story: Calculate data points from observation
Export data from SQL to perform calculations
Current temperature compared to this time yesterday
Last 24h temperature distribution (= today) compared to previous 24h
This weeks' temperature distribution compared to last week, last month, last year
Render using PyGal
Story: Run every hour
It became apparent to me that triggering the colour change when the temperature changed was beyond me. I couldn’t figure out a way to get an external service to trigger a message into my to-be-written code, whilst remaining within the free tier. For example, the Open Weather Map API has a limit of 1,000,000 calls per month. If the API proves to be chatty, and triggers a message every 0.1C, then I could use up even that generous allowance over the course of the month. So instead of having data pushed to me, I decided on scheduling regular polling of data.
Make observation at a time interval
Calculate data points immediately after observation
Create graphs
Story: Visualisation
Create static web page in Flask
Read colours into table in web page (directly into HTML or Flask)
Export bloom colours into SQLite database
Create CSS
CSS to make for nav bar
CSS var() to take row hex from HTML and pass to CSS
CSS for table
Optimised for desktop, tablet, mobile
Use task scheduler to take periodic observations
Build rudimentary CMS
Automatically update web page via CMS
Story: Serve page in local network
Host on the Raspberry Pi
Spikes
Much of this was new to me, so I needed to spend some time researching the topics, undertaking tutorials and practice code, before I could write the application. These were my research spikes, expressed as questions. I recommend you work through the linked tutorials to get your head around the concepts.
How can I access my Raspberry Pi without attaching a keyboard and monitor (as a headless server)?
Which tools should I install and use on my Mac for my development environment?
How do I work with the Philips Hue API?
How do I work with the Open Weather Map API?
I don’t like MatPlotLib for data visualisation in Python. Which alternative should I use?
Having decided to use Flask to generate my website HTML from Python code, how do I use it?
Having decided to use Bootstrap to generate by CSS to format my website, how do I use it?
Having decided to use SQLite for my persistent data stores, how do I use it with Python and Flask?
I want to show the same colours for the same temperature on my Bloom, on the graphs, and on the website. How do I export from the SQLite database into Python, into CSS?
How do I run two programs (the web server and gathering weather observations) simultaneously?
How do I run my program periodically, automatically?
No comments:
Post a Comment
It's always great to hear what you think. Please leave a comment, and start a conversation!