Pat Kavanaugh
2016-01-20 00:20:58 UTC
After a lightning storm in summer 2014 took out the pressure sensor in
one of my two original Dallas 1-wire weather stations, I began
contingency planning against the day when sensor replacements would no
longer be available (now much closer to reality with the regrettable
demise of Hobby Boards). A timely post to the Weather mailing list that
August said nice things about Ambient systems, so I purchased one
(thanks, Tom) and immediately began working out how to divert the data
coming from it, destined to Weather Underground, to a server of my
choice. This was desirable because:
one of my stations was in a remote location with frequent internet
outages, and I wanted to save the data during these
I wanted to keep using the same display and storage infrastructure
I had already put in place for the 1-wire systems
indoor temperature will be available, unlike for Weather Underground
This diversion should work for any weather station that reports to
Weather Underground. The key is a router capable of Destination Network
Address Translation (DNAT). At first I used an old Linksys WRT54G on
which I had installed the DD-WRT Linux-based firmware, later replaced by
a Buffalo WHR-300HP2D with DD-WRT preinstalled. In each case, this was
my main router, but should have also worked providing a subnet for the
weather station to connect to.
I first made sure I could recognize packets coming from the weather
station by assigning it a fixed IP address using the Static Leases
router function.
According to the Weather Underground "Personal Weather Station Upload
Protocol" the data will be sent as an HTTP GET request (TCP port 80), so
I routed packets coming from the weather station to a server of my
choice with the following router Firewall command:
iptables -t nat -I PREROUTING -p tcp -s 192.168.1.38 --dport 80 -j
DNAT --to-destination 192.168.1.132
Here, 192.168.1.38 is the address the router assigned to the
weather station, and 192.168.1.132 is the address of my server to
process the data.
If the destination had been a computer outside the router's local
network, this is probably the only firewall command that would be
needed. With a destination computer on the local network, an additional
command is probably necessary (was on my Buffalo but not on my Linksys)
so that any responses to these packets won't be seen as coming from the
unexpected server address:
iptables -t nat -A POSTROUTING -s 192.168.1.38 -d 192.168.1.132 -p
tcp --dport 80 -j SNAT --to 192.168.1.1
Here, 192.168.1.1 is the local address of the router, which will
then perform the needed translations.
To receive the data, I run a web server (lighttpd on a Raspberry Pi).
Again referring to the "Personal Weather Station Upload Protocol" (or
the server logs) the requests will look like
GET
/weatherstation/updateweatherstation.php?ID=KWhatever&PASSWORD=whatever&indoortempf=60.6&tempf=40.5,
etc.
So I configured the web server to make /weatherstation a CGI directory,
and put a script updateweatherstation.php in it to handle the requests.
Using the "shebang" sequence, it runs as a Bash script (vs PHP). The
measurements are available in the environmental variable QUERY_STRING.
The following commands pass the original request including measurements
on to Weather Underground and generate the desired response text back to
the weather station:
echo 'Status: 200'
echo
curl -s "$SERVER_NAME$REQUEST_URI"
one of my two original Dallas 1-wire weather stations, I began
contingency planning against the day when sensor replacements would no
longer be available (now much closer to reality with the regrettable
demise of Hobby Boards). A timely post to the Weather mailing list that
August said nice things about Ambient systems, so I purchased one
(thanks, Tom) and immediately began working out how to divert the data
coming from it, destined to Weather Underground, to a server of my
choice. This was desirable because:
one of my stations was in a remote location with frequent internet
outages, and I wanted to save the data during these
I wanted to keep using the same display and storage infrastructure
I had already put in place for the 1-wire systems
indoor temperature will be available, unlike for Weather Underground
This diversion should work for any weather station that reports to
Weather Underground. The key is a router capable of Destination Network
Address Translation (DNAT). At first I used an old Linksys WRT54G on
which I had installed the DD-WRT Linux-based firmware, later replaced by
a Buffalo WHR-300HP2D with DD-WRT preinstalled. In each case, this was
my main router, but should have also worked providing a subnet for the
weather station to connect to.
I first made sure I could recognize packets coming from the weather
station by assigning it a fixed IP address using the Static Leases
router function.
According to the Weather Underground "Personal Weather Station Upload
Protocol" the data will be sent as an HTTP GET request (TCP port 80), so
I routed packets coming from the weather station to a server of my
choice with the following router Firewall command:
iptables -t nat -I PREROUTING -p tcp -s 192.168.1.38 --dport 80 -j
DNAT --to-destination 192.168.1.132
Here, 192.168.1.38 is the address the router assigned to the
weather station, and 192.168.1.132 is the address of my server to
process the data.
If the destination had been a computer outside the router's local
network, this is probably the only firewall command that would be
needed. With a destination computer on the local network, an additional
command is probably necessary (was on my Buffalo but not on my Linksys)
so that any responses to these packets won't be seen as coming from the
unexpected server address:
iptables -t nat -A POSTROUTING -s 192.168.1.38 -d 192.168.1.132 -p
tcp --dport 80 -j SNAT --to 192.168.1.1
Here, 192.168.1.1 is the local address of the router, which will
then perform the needed translations.
To receive the data, I run a web server (lighttpd on a Raspberry Pi).
Again referring to the "Personal Weather Station Upload Protocol" (or
the server logs) the requests will look like
GET
/weatherstation/updateweatherstation.php?ID=KWhatever&PASSWORD=whatever&indoortempf=60.6&tempf=40.5,
etc.
So I configured the web server to make /weatherstation a CGI directory,
and put a script updateweatherstation.php in it to handle the requests.
Using the "shebang" sequence, it runs as a Bash script (vs PHP). The
measurements are available in the environmental variable QUERY_STRING.
The following commands pass the original request including measurements
on to Weather Underground and generate the desired response text back to
the weather station:
echo 'Status: 200'
echo
curl -s "$SERVER_NAME$REQUEST_URI"