In Part 1, I looked at using a Presenter device and TTS software to making a talking Raspberry Pi. Here I look at making it talk about the weather - RPi is English after all.
In port, or close to shore, the yachtsman can often pick up an internet connection via a nearby Wifi point (many of us have WiFi boosters) or via a phone connection. There are a number of sources of weather data which typically provide limited free data and more extensive data on subscription. Sadly there is a lack of standardisation of either schema, ontologies or units.
Many amateur stations use Weather Display which uses a simple space delimited text file to save current data for use by visualisation programs such as Weather Display Live. This file is usually web accessible. Here for example is the current data from a station just up the road in Horfield. This map is useful to find stations.
My first design includes:
The Presenter module has been enhanced to accept keyboard cursor keys as well as the Presenter keys. The current presenter is still having problems on the RPi.
The project code is in GitHub
A few aspects of the code are noteworthy:
Cache invalidation
For reasons of efficiency and politeness, a service should not fetch the data unnecessarily, so we need to keep track of how long the data has been held and refresh the local copy from the online data when it is stale.
getter methods need to call refresh() first to ensure getting the latest data.
IDs in XML DOM.
Unlike the DOM in JavaScript which, in the absence of DTD information, assumes that an 'id' attribute is to be treated as the ID for the purposes of getElementById, the python mindom parser makes no such assumption. Thus after loading the menu XML, I need to mark each element with an id attribute as having an ID
Lazy Instatiation
I want to instatiate the Weather objects (aka Station) lazily and provide a way of referencing objects by name to support the use of evaled expressions in the menu. To do this I create an empty dictionary and when a station is referenced in an expression, look first in the dictionary and fall back to creating the object using the properties defined in the menu, and finally save the object in the dictionary:
Word expansion
Spoken text differs from the written text but both are needed, one for the TTS, the other for a screen or logging purposes. Here I have provided a domain-specific dictionary (in weather) and a couple of functions (in speak) to expand abbreviations. A list comprehension provides a neat way to do the expansion:
Whilst the cache invalidation solves one problem, I still have to tackle monitoring - for example to detect a trend in barometric pressure and vocalise a warning if pressure is rising or falling rapidly. This requires two separate processes - one to build up the history by sampling at a fixed inverval determined to the data source and another on a possibly varying interval based on the severity of the warning and the menu option selected. That will be Part3