AMATEUR RADIO • WEATHER • PHP
Tempest Weather to APRS Weather String
Use the WeatherFlow Tempest API, PHP and cron to create
an APRS weather string for BPQ32.
This is a simple command-line PHP integration I use to retrieve
current observations from a Tempest weather station, convert
selected values to the units I need, and write the resulting
APRS weather string to a file that BPQ32 can use.
What This Does
The process is fairly simple.
Tempest Weather Station
→
WeatherFlow REST API
→
PHP Script
→
APRS Weather String
→
BPQ32
The PHP script retrieves the most recent station observation,
converts temperature and wind measurements, builds the weather
string, and prints it to standard output.
A cron job redirects that output into a file. BPQ32 then reads
the file through its WXFileName setting.
What You Need
Tempest Weather Station
You need a WeatherFlow Tempest station associated
with your Tempest account.
Station ID
The REST request needs the numeric station ID for
the Tempest station you want to query.
Personal Access Token
The WeatherFlow API request needs an access token
associated with your account.
PHP
The example is designed to run as a PHP command-line
script on a Linux system.
cron
cron runs the script automatically and creates the
current weather file at regular intervals.
BPQ32
BPQ32 reads the resulting weather string from the
file specified by WXFileName.
STEP 1
Get Your Tempest API Information
You need two values before the script can retrieve your
weather observations:
########
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
WeatherFlow provides Personal Access Tokens for simple
personal integrations such as command-line scripts.
Keep your access token private.
Do not publish your real token in a web page, public
repository, screenshot or example configuration.
The current WeatherFlow API documentation is available here:
STEP 2
Retrieve the Latest Station Observation
WeatherFlow provides a REST endpoint for retrieving the latest
observation from a station.
The request used by this script follows this form:
https://swd.weatherflow.com/swd/rest/observations/station/STATION_ID?token=ACCESS_TOKEN
In the PHP script, replace:
with your station ID
with your access token
STEP 3
Create the PHP Script
This is a cleaned-up version of the original command-line
script while preserving the same output format.
I use a filename such as:
<?php
/*
* Tempest Weather to APRS Weather String
*
* Replace the station ID, access token,
* latitude and longitude with your values.
*/
/* ---------------------------------------------------------
* Configuration
* --------------------------------------------------------- */
$station_id = '########';
$access_token =
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
/*
* APRS position.
*
* Change these to the latitude and longitude
* appropriate for your station.
*/
$latitude = '3941.42N';
$longitude = '10446.43W';
/* ---------------------------------------------------------
* Build the Tempest API URL
* --------------------------------------------------------- */
$url =
'https://swd.weatherflow.com/swd/rest/' .
'observations/station/' .
rawurlencode($station_id) .
'?token=' .
rawurlencode($access_token);
/* ---------------------------------------------------------
* Retrieve the JSON data
* --------------------------------------------------------- */
$jsondata = @file_get_contents($url);
if ($jsondata === false) {
fwrite(
STDERR,
"ERROR: Unable to retrieve Tempest data.\n"
);
exit(1);
}
/* ---------------------------------------------------------
* Decode JSON
* --------------------------------------------------------- */
$result = json_decode(
$jsondata,
true
);
if (!is_array($result)) {
fwrite(
STDERR,
"ERROR: Invalid JSON returned by Tempest API.\n"
);
exit(1);
}
/*
* Uncomment this while testing if you want
* to see everything returned by the API.
*/
/*
print_r($result);
*/
/* ---------------------------------------------------------
* Make sure an observation exists
* --------------------------------------------------------- */
if (
!isset($result['obs'][0]) ||
!is_array($result['obs'][0])
) {
fwrite(
STDERR,
"ERROR: No observation returned.\n"
);
exit(1);
}
$obs = $result['obs'][0];
/* ---------------------------------------------------------
* Convert units
* --------------------------------------------------------- */
/*
* Celsius to Fahrenheit
*/
$tempf = round(
($obs['air_temperature'] * 1.8) + 32
);
/*
* Meters/second to miles/hour
*/
$wind_speed = round(
$obs['wind_avg'] * 2.237
);
$wind_gust = round(
$obs['wind_gust'] * 2.237
);
/* ---------------------------------------------------------
* Build the APRS weather string
* --------------------------------------------------------- */
echo
"_" .
$latitude .
"/" .
$longitude .
"_" .
$obs['wind_direction'] .
"/" .
$wind_speed .
"G" .
$wind_gust .
"T" .
$tempf .
"P" .
$obs['precip'] .
"h" .
$obs['relative_humidity'] .
"b" .
$obs['barometric_pressure'] .
"\n";
?>
Weather Values Used by the Script
The script uses the following values from the current
Tempest observation:
air_temperature
wind_avg
wind_gust
wind_direction
precip
relative_humidity
barometric_pressure
The original Tempest values for temperature and wind are
converted before they are inserted into my output string.
STEP 4
Test the Script Manually
Before adding cron or BPQ32, make sure the PHP script works
by itself.
Run:
/usr/bin/php /usr/local/bpq32/weatherdecode.php
The script should print one weather string and return to
the command prompt.
Test each part separately.
First prove that the Tempest API request works.
Then prove that PHP creates the weather string.
Only after that should you automate it with cron
and connect it to BPQ32.
STEP 5
Generate the Weather File With cron
Once the script works correctly from the command line,
cron can update the weather file automatically.
My cron entry runs the script every five minutes:
*/5 * * * * /usr/bin/php /usr/local/bpq32/weatherdecode.php > /usr/local/bpq32/current.txt
The > redirects the script output into:
Each run replaces the previous contents with the most recent
weather string.
Check the Generated File
cat /usr/local/bpq32/current.txt
Do this before configuring BPQ32. If the file does not contain
the expected weather data, BPQ32 is not the problem yet.
STEP 6
Configure BPQ32
Once the weather file is being generated correctly, tell
BPQ32 where to find it.
In bpq32.cfg, locate the
WXFileName setting and configure:
WXFileName=/usr/local/bpq32/current.txt
Restart BPQ32 after changing the configuration so that the
updated setting is loaded.
If It Doesn’t Work
No Output From the Script
Run the script manually rather than through cron.
Check the station ID, access token, network connection,
and any error written to the terminal.
API Data Is Returned but the Script Fails
Temporarily uncomment the print_r($result)
line and inspect the data returned by the API.
Manual Run Works but cron Does Not
Check the full PHP path, script permissions,
output-directory permissions and the environment
used by cron.
current.txt Is Empty
Run the exact command from the cron entry manually.
If PHP exits with an error, shell redirection can
leave the output file empty.
Weather File Is Correct but BPQ32 Does Not Use It
Check the WXFileName path and make sure
BPQ32 can read the file.
Data Looks Wrong
Check the raw Tempest observation before changing
the APRS output logic. Determine whether the problem
is the source data, the unit conversion, or the
output string.
A Note About the Access Token
The simple example above keeps the access token directly
in the PHP file because that is how the original script
was written.
If the system has multiple users, the script is stored in
a shared location, or the file may ever be copied to a public
repository, protect the token appropriately.
Do not publish the real access token.
The values shown in this page are placeholders.
Configuration Summary
/usr/local/bpq32/weatherdecode.php
/usr/local/bpq32/current.txt
Every 5 minutes
WXFileName
Keep It Simple
There are more elaborate ways to integrate weather data with
amateur-radio software, but this approach has a useful advantage:
each part can be tested independently.
Retrieve the data.
Build the string.
Write the file.
Let BPQ32 read it.
If something stops working, start at the beginning and prove
each layer before moving to the next one.