I have always enjoyed the weather and attempting to forecast what it will do. I purchased a Davis Vantage Pro 2 weather station two years ago. After years of using el-cheapo weather stations, this reliability has been top-notch. You can also purchase replacement parts, but I have not had the requirement.
As part of this autistic experimentation, I like to share my weather data with multiple weather sites, including
My Weatherlink live supports uploading to the first two sites as a direct feed of the Weatherlink website. But Windy is not located there as an option. However, the Weatherlink live has a local API that I can poll every five minutes via cron and a Python script running on one of my Ubuntu virtual machines.
Hopefully, someone else out there will find this of use.
#!/bin/python3
#Copyright 2019 STEPHEN SCHWETZ
#Copyright 2019 RODOLFO QUESADA ZUMBADO
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#requires python-pytz pkg (installed via pip or pkg manager)
import urllib.request, json
from datetime import datetime
from pytz import timezone
import time
import urllib.parse
import re
#enable debugging?
DEBUG=False
#address of weatherlink live
bucket_type = 0.2
local_address = "172.23.23.12"
windy_api_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjaSI6MTUxMjgzNCwiaWF0IjoxNjU2ODYxNDU1fQ.GB1tUsSAblbhMR0nC-mfD4GWCPB1C-0NJCkE8iFezYU"
# davis wetherlink live local api
#https://weatherlink.github.io/weatherlink-live-local-api/
# windy api docs
# https://community.windy.com/topic/8168/report-you-weather-station-data-to-windy
# davis json api
json_noaa_ext_url="http://"+local_address+"/v1/current_conditions"
print ("\n")
if DEBUG:
print(json_noaa_ext_url)
with urllib.request.urlopen(json_noaa_ext_url) as url:
weatherlink_data = json.loads(url.read().decode())
# windy api
# station - 32 bit integer; required for multiple stations; default value 0; alternative names: si, stationId
# shareOption - text one of: Open, Only Windy, Private; default value is Open
# name - text; user selected station name
# longitude - number [degrees]; required; east–west position on the Earth`s surface
# elevation - number [metres]; height above the Earth's sea level (reference geoid); alternative names: elev, elev_m, altitude
# tempheight - number [metres]; temperature sensor height above the surface; alternative names: agl_temp
# windheight - number [metres]; wind sensors height above the surface; alternative names: agl_wind
# measurements
# station - 32 bit integer; required for multiple stations; default value 0; alternative names: si, stationId
# time - text; iso string formated time "2011-10-05T14:48:00.000Z"; when time (or alternative) is NOT present server time is used
# dateutc - text; UTC time formated as "2001-01-01 10:32:35"; (alternative to time)
# ts - unix timestamp [s] or [ms]; (alternative to time)
# temp - real number [°C]; air temperature
# tempf - real number [°F]; air temperature (alternative to temp)
# wind - real number [m/s]; wind speed
# windspeedmph - real number [mph]; wind speed (alternative to wind)
# winddir - integer number [deg]; instantaneous wind direction
# gust - real number [m/s]; current wind gust
# windgustmph - real number [mph]; current wind gust (alternative to gust)
# rh - real number [%]; relative humidity ; alternative name: humidity
# dewpoint - real number [°C];
# pressure - real number [Pa]; atmospheric pressure
# baromin - real number [inches Hg];
# precip - real number [mm]; precipitation over the past hour
# rainin - real number [in]; rain inches over the past hour (alternative to precip)
# uv - number [index];
windy_data = {}
### must url-escape this value properly, later!
temp_c = ((float(weatherlink_data['data']['conditions'][0]["temp"]) - 32) * 5/9)
windy_data["temp"] = str(temp_c)
windy_data["windspeedmph"] = str(weatherlink_data['data']['conditions'][0]["wind_speed_avg_last_10_min"])
#If the wind direction is not None set the wind direction
if str(weatherlink_data['data']['conditions'][0]["wind_dir_scalar_avg_last_10_min"]) != "None":
windy_data["winddir"] = str(weatherlink_data['data']['conditions'][0]["wind_dir_scalar_avg_last_10_min"])
windy_data["windgustmph"] = str(weatherlink_data['data']['conditions'][0]["wind_speed_hi_last_10_min"])
windy_data["rh"] = str(weatherlink_data['data']['conditions'][0]["hum"])
dewpoint_c = ((float(weatherlink_data['data']['conditions'][0]["dew_point"]) - 32) * 5/9)
windy_data["dewpoint"] = str(dewpoint_c)
windy_data["baromin"] = str(weatherlink_data['data']['conditions'][2]["bar_sea_level"])
windy_data["precip"] = str(float(weatherlink_data['data']['conditions'][0]["rainfall_last_60_min"] * bucket_type))
#windy_data["uv"] = weatherlink_data["davis_current_observation"]["uv_index"]
windy_data["dateutc"]= urllib.parse.quote(str(datetime.utcfromtimestamp(weatherlink_data["data"]["ts"]).strftime('%Y-%m-%d %H:%M:%S')))
windy_url = "https://stations.windy.com/pws/update/"+windy_api_key+"?temp="+windy_data["temp"]+""
for k,v in windy_data.items():
if k != "temp":
windy_url+="&"+k+"="+v
if DEBUG:
print(windy_url)
windy_response = re.sub('<br\s*?>', '\n', urllib.request.urlopen(windy_url).read().decode("utf-8"))
#if DEBUG:
# print(windy_response)
if 'cooldown' in windy_response:
print("Windy Update Failed due to backpressure\n")
print(windy_response)
elif 'SUCCESS' in windy_response:
print("Windy updated OK")
else:
print("Windy Update failed\n")
print(windy_response)
print ("\n")