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 whose 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 in configuration.yaml: ```yaml shell_command: curl_get: 'curl -X GET {{ url }}' ``` Automation config example: ```yaml 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 - atmospheric_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 device_class: wind_speed default: '' sensor_windgust: name: Wind gust sensor selector: entity: domain: sensor device_class: wind_speed default: '' sensor_winddir: name: Wind direction sensor selector: entity: domain: sensor device_class: wind_direction default: '' sensor_windgustdir: name: Wind Gust direction sensor selector: entity: domain: sensor device_class: wind_direction 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 device_class: irradiance 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 default: '300' trigger_entities: name: Trigger entities selector: entity: multiple: true filter: domain: sensor default: '' curl_command_service: name: CURL command service selector: text: default: 'shell_command.curl_get' 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_windgustdir: !input sensor_windgustdir 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: > {% set candidate_wind_direction = states(sensor_winddir) %} {% set wind_direction_float = candidate_wind_direction | float(default=-1) %} {% if wind_direction_float == -1 %} {% set directions_map16 = {'N': 0, 'NNE': 22.5, 'NE': 45, 'ENE': 67.5, 'E': 90, 'ESE': 112.5, 'SE': 135, 'SSE': 157.5, 'S': 180, 'SSW': 202.5, 'SW': 225, 'WSW': 247.5, 'W': 270, 'WNW': 292.5, 'NW': 315, 'NNW': 337.5} %} {% set candidate_wind_direction = candidate_wind_direction.upper() %} {{ directions_map16.get(candidate_wind_direction, '') | float(default=0) }} {%- else -%} {{ wind_direction_float }} {%- endif %} windgustdir: > {% set candidate_windgust_direction = states(sensor_windgustdir) %} {% set windgust_direction_float = candidate_windgust_direction | float(default=-1) %} {% if windgust_direction_float == -1 %} {% set directions_map16 = {'N': 0, 'NNE': 22.5, 'NE': 45, 'ENE': 67.5, 'E': 90, 'ESE': 112.5, 'SE': 135, 'SSE': 157.5, 'S': 180, 'SSW': 202.5, 'SW': 225, 'WSW': 247.5, 'W': 270, 'WNW': 292.5, 'NW': 315, 'NNW': 337.5} %} {% set candidate_windgust_direction = candidate_windgust_direction.upper() %} {{ directions_map16.get(candidate_windgust_direction, '') | float(default=0) }} {%- else -%} {{ windgust_direction_float }} {%- endif %} 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) | float(default=0) / 126.7) ) 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] ,['windgustdir', windgustdir] ,['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 }}"