The weather forecasts I described in a previous post have the advanage of being very specific. However, they are not very useful for others located outside of my local area. In fact, the Environment Canada public forecasting texts do not lend themselves to ad hoc consultation for any arbitrary place in Canada. Of course, they are useless for any place outside the country.
Among other similar sites, the venerable Yahoo! offers an application programming interface (API) for weather forecasts with four good qualities. Its geographical coverage is quite good. Access is free with no registration requirement to obtain a key. It is possible to specify the location by its name and possibly its region or country if there is a possibility of ambiguity. Did you know that Paris is less than an hour from Stratford in Ontario (Canada)? Finally, the data is provided in a file in JSON format that I find much simpler than XML.
I wrote yw.pas, a small unit in Pascal (Free Pascal) that
formulates the HTTPS request based on the desired meteorological data and
retrieves the results from the Yahoo! Server. Here
is the main part of the interface part of the unit.
Three types are declared including TYahooWeatherErr for the exceptions
that could occur with the main function YahooWeatherJSONData that we will see
later.
The TWeatherElements (note the final "s") type denotes a set
of TWeatherElement. Each member of this enumeration identifies
data to retrieve. The most important are weCondition and
weForecast to obtain, respectively, the current conditions and
forecasts for the current day and the next nine days. Since there may be a
misunderstanding about the location, it is best to always get the data
identifying it by adding weLocation. The units of measurement
should also be requested with weUnits because the data are just
numeric values. With weWind, we get the wind speed and direction
as well as the wind effect, with wdAtmosphere it is humidity,
barometric pressure and current visibility that are provided. Sunrise and
sunset times are collected with weAstronomy (local time).
The YahooWeatherUrl function returns the HTTP request to
submit to Yahoo! to obtain desired
meteorological data. The parameters of the function are:
| location | name of the locality and optionally its region and country (eg "Paris,
On" - for Paris, Ontario, Canada).
We can also put the coordinates of a place (ex "(40.7141667, -74.0063889)" for New York, New York) |
| elements | set of desired meteorological elements to include in the output
(default: [weLocation, weCondition]).
|
| celsius | set to true for measurements in International System units,
set to false for measurements in imperial units
(which are hardly used anywhere else than in the United States)
(default: true - SI measures)
|
| json | set to true for the output to be in JSON format,
set to false so that the output in XML format,
(default: true - JSON) |
The YahooWeatherRawData function returns the raw data
obtained from Yahoo! Weather. If an error occurs,
the returned string will be an error message that begins with the word
"ERROR" or its translated equivalent.
Both of these functions are used by the unit's main function,
YahooWeatherJSONData, which turns plain text into a
TJSONData object. If an error occurs, a
TYahooWeatherErr exception is raised with the message returned
by the YahooWeatherRawData function. Destruction of the ojbect
when no longer needed is up to the caller. So the typical use of the function
looks like this.
To simplify the use of the TJSONData object obtained with
the previous function, a fourth function is provided:
GetWeatherElement. This function takes as arguments
Wanted a desired weather element and src the
TJSONData object to return a TJSONObject in
the variable elem variable that the caller can use to
retrieve the data associated with the element. Since it is an object, it is actually a pointer to the data
belonging to the object src of type TJSONData. Do
not destroy the elem object as this would cause an exception
when destroying src. If the element is not present, the function
returns false. This function can be used to retrieve data for an
element that was not requested without causing an error. Consequently, it is
not necessary to preserve the value of the elements parameter of the
function YahooWeatherJSONData. One can proceed as below.
The Strings property of
TJSONObject could be used if there is no need to modify the
displayed numerical values.
The TForm1.WeatherText function in unit
main.pas of the yweather application shows all the
selectors that can be used with each
meteorological element. By the way, here is a screen shot of the program
in action.
It's not very pretty I agree, but please make allowances for the goal of
this exercise which is to transform the data obtained from the Web into
a text that can be said by a speech synthesis program. What we can see is a
good start, but there is still more to do. The hours in the format hh:mm,
the degrees °C, the speed km/h are understood by pico tts.
On the other hand, the abbreviation mb is not supported, nor the directions
like SW, E and and so on. Moreover, parentheses do not tranlate well into sound.
According to the documentation, pressure is measured in psi
(pounds per square inch) when imperial measures are requested. This is not
correct, it is obvioulsy measured in inches of mercury («in Hg») as shown
on the Weather
page of Yahoo. But there is more. Look at the barometric pressure on the
screenshot above, it is clearly wonky. Pressure over 33,000 millibars is
about 34 times what it should be. If imperial measures are chosen, the
returned value will again be 34 times greater than it should be. It appears
that an additional conversion factor (1 inch Hg = 33.8639 mb) was introduced
in the calculation of the values. The problem has been known for at least a
year as evidenced by these two discussions on forums Yahoo weather API returning bad value for pressure and Barometric pressure reading seems wrong. Since a
correction does not seem to be forthcoming, unit yw.pas
contains the FIX_PRESSURE directive used to activate a rather
unsophisticated fix. In the future, should the pressure values appear to be
way too low (about 34 times lower than they should be), eliminate the
directive because it means that Yahoo finally
corrected the problem.
This delay in making a minor correction, the dilapidated state of the developer site (lack of information, links to pages that no longer exist ...) and uncertainty about the future of Yahoo since its purchase by Verizon do not inspire confidence. Will the service still be in place in a few months? Here is a list of possible replacements for the Yahoo! Weather along with the maximum number of queries in one minute, one hour or one day that must not be exceeded to maintain free access. Note, however, that you must obtain a key from each of these services that must be added to requests.
| Maxmimu requests per | ||||
| Name | Address | minute | hour | day |
| OpenWeatherMap | http://www.openweathermap.com/ | 60 | ||
| AccuWeather | https://developer.accuweather.com | 50 | ||
| WeatherUnderground | https://www.wunderground.com/ | 10 | 500 | |
| Dark Sky | https://darksky.net/dev/ | 1000 | ||
| Apixu | https://www.apixu.com/ | 1000 | ||
| Weatherbit.io | https://www.weatherbit.io/ | 75 | ||
I will be able to test the Dark Sky forecasting service (formerly forecast.io) in the future since I already have an account with this provider. My home automation server gets data from this account every five minutes.
The Domoticz log seems to indicate that there are six separate queries every 5 minutes. But the daily limit would be exceeded at this rate. So there must be only one big query every five minutes that Domoticz splits in six which matches the six devices associated with Dark Sky created by the application and displayed in the Weather tab. It would be possible to make up to 712 ad hoc forecast requests per day without exceeding the limits for free use.
References
- Yahoo Weather API for your apps
- https://developer.yahoo.com/weather/
- YQL at Yahoo! Developer Network
- https://developer.yahoo.com/yql/guide/
- Lazarus Pascal - Retrieve Yahoo Weather Forecast by Hans Luijten
- https://www.tweaking4all.com/software-development/lazarus-development/yahoo-weather-forecast/
Download
The yweather.zip archive contains the source code for the
yweather program demonstrating the use of the yw.pas
unit.
- Programming Language: Free Pascal / Lazarus
- Requirements:
Ararat Synapselibrary.
I used version 40.1 which can be obtained from Sourceforge.- If the secure HTTPS protocol is used (as recommended) then an
encryption library is needed.
I usedopensshalready installed in Ubuntu. The development packagelibsslhad to be installed:michel@hp:~$ sudo apt install libssl-devFor Windows and Mac OS see the article by Hans Luijten.
- License : BSD type which is pretty liberal when it comes to using the source code but which denies all responsibility.
- Natural Language: English is used in the program and in unit
yw.pas. However, the code is written so that it should be easy to adapt to other languages just be translating thelanguages/yweather.pofile. A French language translation is provided and will automatically be used on systems with a French locale. - Link: https://sigmdel.ca/michel/program/fpl/yweather/dnld/yweather.zip