Description
A blueprint to upload Home Assistant sensor data to WUnderground.
The WUnderground data upload for weather stations is based on a GET request, so it is possible to achieve these results within an automation.
Yes, I know. WUnderground pulled a free service down, but I support the idea of a community based weather station.
This blueprint needs to execute a shell_command. This service needs to be enabled with, for example, the following YAML.
shell_command:
curl_get: 'curl -X GET {{ url }}'
Disclaimer
The blueprint is created because the Netatmo to WUnderground upload isnât working (itâs possible in the WUnderground âadd stationâ wizard, but fails). The sensor data is formatted based on the information in my available sensors and unit_of_measurement values, so there could be a bug in formatting.
Blueprint
blueprint:
name: WUnderground upload
description: >
Upload data from Home Assistant to WUnderground.
Config:
The station_id and station_key variable must be fetched from WUnderground.
The sensor_* variables are the sensors whos data will be uploaded
The trigger_entities variable specifies the entries to trigger state changes on (this could be a list)
The curl_command_service variable specifies the CURL-service to execute.
The refresh_frequency variable specifies the frequency the sensors update their data
The dewpoint temperature can be calculated based on the outdoor temperature and the outdoor humidity.
By default, it will be calculated, to disable this set calculate_dewpt to false.
The CURL-service must exist in Home Assistant.
This can be configured with the following YAML
shell_command:
curl_get: 'curl -X GET {{ url }}'
Automation config example:
automation:
- id: wunderground_data_upload
alias: WUnderground data upload
use_blueprint:
path: wunderground_upload.yaml
input:
station_id: !secret wunderground_station_id
station_key: !secret wunderground_station_key
sensor_baro: 'sensor.outdoor_pressure'
sensor_temp: 'sensor.outdoor_temperature'
sensor_humidity: 'sensor.outdoor_humidity'
sensor_rain: 'sensor.outdoor_rain'
sensor_dailyrain: 'sensor.outdoor_rain_today'
refresh_frequency: 300
trigger_entities:
- sensor.outdoor_temperature
- sensor.outdoor_humidity
- sensor.outdoor_rain
- sensor.outdoor_rain_today
curl_command_service: shell_command.curl_get
domain: automation
source_url: "https://github.com/dvandonkelaar/home-assistant-blueprints/raw/main/wunderground_upload.yaml"
input:
station_id:
name: Station ID
default: ''
station_key:
name: Station key
default: ''
sensor_baro:
name: Barometer sensor
selector:
entity:
domain: sensor
device_class: pressure
default: ''
sensor_temp:
name: Temperature sensor
selector:
entity:
domain: sensor
device_class: temperature
default: ''
sensor_dewpt:
name: Dew point sensor
selector:
entity:
domain: sensor
device_class: temperature
default: ''
calculate_dewpt:
name: Calculate dewpoint
description:
Dewpoint calculation is only possible if the outdoor temperature and outdoor humidity sensor are available.
selector:
boolean:
default: true
sensor_humidity:
name: Humidity sensor
selector:
entity:
domain: sensor
device_class: humidity
default: ''
sensor_windspeed:
name: Wind speed sensor
selector:
entity:
domain: sensor
default: ''
sensor_windgust:
name: Wind gust sensor
selector:
entity:
domain: sensor
default: ''
sensor_winddir:
name: Wind direction sensor
selector:
entity:
domain: sensor
default: ''
sensor_rain:
name: Rain sensor
selector:
entity:
domain: sensor
default: ''
sensor_dailyrain:
name: Daily rain sensor
selector:
entity:
domain: sensor
default: ''
sensor_indoortemp:
name: Indoor temperature sensor
selector:
entity:
domain: sensor
device_class: temperature
default: ''
sensor_indoorhumidity:
name: Indoor humidity sensor
selector:
entity:
domain: sensor
device_class: humidity
default: ''
sensor_solarradiation:
name: Solar Radiation sensor
selector:
entity:
domain: sensor
default: ''
sensor_UV:
name: UV Index sensor
selector:
entity:
domain: sensor
default: ''
refresh_frequency:
name: Refresh frequency (seconds)
selector:
number:
min: 1
max: 10800
step: 1
unit_of_measurement: seconds
trigger_entities:
name: Trigger entities
selector:
entity:
default: ''
curl_command_service:
name: CURL command service
selector:
text:
default: ''
delay:
name: Delay after publishing results
selector:
number:
min: 0
max: 10800
step: 1
unit_of_measurement: seconds
default: 10
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: !input trigger_entities
variables:
station_id: !input station_id
station_key: !input station_key
sensor_baro: !input sensor_baro
sensor_temp: !input sensor_temp
sensor_dewpt: !input sensor_dewpt
calculate_dewpt: !input calculate_dewpt
sensor_humidity: !input sensor_humidity
sensor_windspeed: !input sensor_windspeed
sensor_windgust: !input sensor_windgust
sensor_winddir: !input sensor_winddir
sensor_rain: !input sensor_rain
sensor_dailyrain: !input sensor_dailyrain
sensor_indoortemp: !input sensor_indoortemp
sensor_indoorhumidity: !input sensor_indoorhumidity
sensor_solarradiation: !input sensor_solarradiation
sensor_UV: !input sensor_UV
rtfreq: !input refresh_frequency
delay: !input delay
baromin: >
{% set unit_of_measurement = state_attr(sensor_baro, 'unit_of_measurement') %}
{{ sensor_baro if sensor_baro == ''
else (states(sensor_baro) | float(default=0)) if unit_of_measurement not in ['mbar', 'hPa']
else ((states(sensor_baro) | float(default=0)) / 33.8639) }}
tempf: >
{% set unit_of_measurement = state_attr(sensor_temp, 'unit_of_measurement') %}
{{ sensor_temp if sensor_temp == ''
else ((states(sensor_temp) | float(default=0)) if unit_of_measurement == '°F'
else ((states(sensor_temp) | float(default=0)) * 1.8) + 32) }}
humidity: >
{{ sensor_humidity if sensor_humidity == '' else (states(sensor_humidity) | float(default=0)) }}
windspeedmph: >
{% set unit_of_measurement = state_attr(sensor_windspeed, 'unit_of_measurement') %}
{{ sensor_windspeed if sensor_windspeed == ''
else (states(sensor_windspeed) | float(default=0)) * (0.6213 if unit_of_measurement == 'km/h' else 1) }}
windgustmph: >
{% set unit_of_measurement = state_attr(sensor_windgust, 'unit_of_measurement') %}
{{ sensor_windgust if sensor_windgust == ''
else (states(sensor_windgust) | float(default=0)) * (0.6213 if unit_of_measurement == 'km/h' else 1) }}
winddir: >
{{ sensor_winddir if sensor_winddir == ''
else (states(sensor_winddir) | float(default=0)) }}
rainin: >
{% set unit_of_measurement = state_attr(sensor_rain, 'unit_of_measurement') %}
{{ sensor_rain if sensor_rain == ''
else ((states(sensor_rain) | float(default=0)) / (25.4 if unit_of_measurement == 'mm' else 1)) }}
dailyrainin: >
{% set unit_of_measurement = state_attr(sensor_dailyrain, 'unit_of_measurement') %}
{{ sensor_dailyrain if sensor_dailyrain == ''
else ((states(sensor_dailyrain) | float(default=0)) / (25.4 if unit_of_measurement == 'mm' else 1)) }}
indoortempf: >
{% set unit_of_measurement = state_attr(sensor_indoortemp, 'unit_of_measurement') %}
{{ sensor_indoortemp if sensor_indoortemp == ''
else ((states(sensor_indoortemp) | float(default=0)) if unit_of_measurement == '°F'
else ((states(sensor_indoortemp) | float(default=0)) * 1.8) + 32) }}
indoorhumidity: >
{{ sensor_indoorhumidity if sensor_indoorhumidity == ''
else (states(sensor_indoorhumidity) | float(default=0)) }}
solarradiation: >
{% set unit_of_measurement = state_attr(sensor_solarradiation, 'unit_of_measurement') %}
{{ sensor_solarradiation if sensor_solarradiation == ''
else ((states(sensor_solarradiation) / 126.7) | float(default=0)) if unit_of_measurement == 'lux'
else (states(sensor_solarradiation) | float(default=0)) }}
UV: >
{{ sensor_UV if sensor_UV == ''
else (states(sensor_UV) | int(default=0)) }}
dewptf_calculated: >
{% set unit_of_measurement = state_attr(sensor_temp, 'unit_of_measurement') %}
{% set T = ((states(sensor_temp) | float(default=0)) if unit_of_measurement == '°C'
else ((states(sensor_temp) | float(default=0)) - 32) / 1.8) %}
{% set RH = humidity %}
{% set dewpt = '' %}
{% if sensor_temp != '' and sensor_humidity != '' %}
{% set A = log(RH / 100, default=0.0) + (17.62 * T / (243.12 + T)) %}
{% set dewpt = 243.12 * A / (17.62 - A) %}
{% set dewpt = (dewpt * 1.8) + 32 %}
{% endif %}
{{ dewpt }}
dewptf: >
{% set unit_of_measurement = state_attr(sensor_dewpt, 'unit_of_measurement') %}
{{ (dewptf_calculated if calculate_dewpt is true
else sensor_dewpt) if sensor_dewpt == ''
else ((states(sensor_dewpt) | float(default=0)) if unit_of_measurement == '°F'
else ((states(sensor_dewpt) | float(default=0)) * 1.8) + 32) }}
payload: >
{% set data = namespace(sensors=[]) %}
{% for i in [['rtfreq', rtfreq]
,['baromin', baromin]
,['tempf', tempf]
,['dewptf', dewptf]
,['humidity', humidity]
,['windspeedmph', windspeedmph]
,['windgustmph', windgustmph]
,['winddir', winddir]
,['rainin', rainin]
,['dailyrainin', dailyrainin]
,['indoortempf', indoortempf]
,['indoorhumidity', indoorhumidity]
,['solarradiation', solarradiation]
,['UV', UV]
]%}
{% if i[1] != '' %}
{% set data.sensors = data.sensors + ['{}={}'.format(i[0], (i[1] if i[0] == 'rtfreq'
else (i[1] | round(3)) | string))] %}
{% endif %}
{% endfor %}
{% set _payload = 'ID=' + station_id %}
{% set _payload = _payload + '&PASSWORD=' + station_key %}
{% set _payload = _payload + '&action=updateraww' %}
{% set _payload = _payload + '&realtime=1' %}
{% set _payload = _payload + '&dateutc=now' %}
{% set _payload = _payload + '&' if data.sensors | length > 0 else '' %}
{% set _payload = _payload + data.sensors | join('&') %}
{{ _payload }}
action:
- alias: "Check if station_id and station_key exist"
if: >
{{ station_id != ''
and station_key != ''
}}
then:
- service: !input curl_command_service
data:
url: "https://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?{{ payload }}"
- alias: "Wait to prevent multiple uploads"
delay:
seconds: "{{ delay | int }}"
Automation example
automation:
- id: wunderground_data_upload
alias: WUnderground data upload
use_blueprint:
path: wunderground_upload.yaml
input:
station_id: !secret wunderground_station_id
station_key: !secret wunderground_station_key
sensor_baro: 'sensor.outdoor_pressure'
sensor_temp: 'sensor.outdoor_temperature'
sensor_humidity: 'sensor.outdoor_humidity'
sensor_rain: 'sensor.outdoor_rain'
sensor_dailyrain: 'sensor.outdoor_rain_today'
refresh_frequency: 300
trigger_entities:
- sensor.outdoor_temperature
- sensor.outdoor_humidity
- sensor.outdoor_rain
- sensor.outdoor_rain_today
curl_command_service: shell_command.curl_get