šŸŒ¤ WUnderground data uploader

In the end it was a simple typo with the station ID. After updating that, everything works perfectly and has been working great for over a month now.

Thanks for the blueprint!

Hi there. Great blueprint. I have two recommondations:

  • for the pressure, you should also allow devices of type barometric_pressure, else, we are missing some devices in the drop down, for example netatmo devices.
  • For the current precipitation, some devices give mm/h as a unit, not only mm. If they do, you donā€™t convert into inches.
    Regards, Edi

Hi @eiten,

Thanks for the suggestion! I added barometric_pressure to the entity selector in this branch.
Can you check if this works for you?

For a precipitation with a unit of measurement of mm/h, we need to convert this to a total precipitation to work for WUnderground. If I recall the request documentation correctly.

Slightly off topic (hope you donā€™t mind Dirk), but in case of interest to anyone Iā€™ve been able to tweak an Automation created from this Blueprint to allow upload to the Weather Observation Website (WOW) from Met Ɖireann in Ireland which in itself is part of the Global WOW network of crowdsourced weather observations.
The Met Ɖireann WOW upload piggybacks on the UK Met Office site (here) and their API is documented here.

The upload structure is very similar to the WUnderground one so it was really a case of 1) change upload URL 2) changing the Station/Site ID naming and 3) removing the sensors from the payload that WUnderground has but WOW doesnā€™tā€¦

1 Like

Hi @Gav_in,

No problem, I was meaning to look into uploading to WOW after creating the WUnderground blueprint but havenā€™t made time to look into it.
Can you share how you dit this (or create a PR on my GitHub)? I was planned to tweak the blueprint to support both WUnderground and WOW (and maybe also other services) so this very helpfull.

1 Like

No worriesā€¦given that Iā€™ve butchered an Automation created from your Blueprint rather than updated it to work with two services, Iā€™ll post the full edited automation code here rather than a PRā€¦

The changes Iā€™ve made areā€¦

URL is now url: http://wow.metoffice.gov.uk/automaticreading?{{ payload }}
PAYLOAD after removing data that WOW doesnā€™t need, changing the names for some of the variables, and adding in a ā€œ&softwaretypeā€ tag is now ā€¦

    {% 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]
          ]%}
      {% 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 = 'siteid=' + station_id %} {% set _payload = _payload +
    '&siteAuthenticationKey=' + station_key %} {% set _payload = _payload +
    '&dateutc=now' %} {% set _payload = _payload + '&' if data.sensors | length
    > 0 else '' %} {% set _payload = _payload + data.sensors | join('&') %} {%
    set _payload = _payload + '&softwaretype=homeassistant' %} {{ _payload }}

Also had to enclose my station_key into " as itā€™s a number for this service so was seen as int rather than str and couldnā€™t concatenate into the URL

And Iā€™ve added a 30 sec delay before the CURL command so that my WUnderground and WOW commands arenā€™t firing at exactly the same time.


FULL AUTOMATION

description: >-
  adapted from WUnderground Uploader Blueprint
  https://community.home-assistant.io/t/wunderground-data-uploader/330332
triggers:
  - entity_id:
      - sensor.my_wind_strength
      - sensor.my_wind_gust_strength
      - sensor.my_rain_rain
      - sensor.my_outdoor_temperature
      - sensor.my_humidity
    trigger: state
actions:
  - alias: Check if station_id and station_key exist
    if:
      - condition: template
        value_template: |
          {{      station_id != ''
              and station_key != ''
          }}
    then:
      - delay:
          hours: 0
          minutes: 0
          seconds: 30
          milliseconds: 0
      - data:
          url: http://wow.metoffice.gov.uk/automaticreading?{{ payload }}
        action: shell_command.curl_get
  - alias: Wait to prevent multiple uploads
    delay:
      seconds: "{{ delay | int }}"
mode: single
max_exceeded: silent
variables:
  station_id: LONG_CODE_FOR_YOUR_WOW_STATION_ID
  station_key: "six digit code"
  sensor_baro: sensor.my_outdoor_pressure
  sensor_temp: sensor.my_outdoor_temperature
  sensor_dewpt: ""
  calculate_dewpt: true
  sensor_humidity: sensor.my_outdoor_humidity
  sensor_windspeed: sensor.my_wind_wind_strength
  sensor_windgust: sensor.my_wind_gust_strength
  sensor_winddir: sensor.my_wind_wind_direction
  sensor_rain: sensor.my_rain_rain
  sensor_dailyrain: sensor.my_rain_rain_today
  sensor_indoortemp: ""
  sensor_indoorhumidity: ""
  sensor_solarradiation: ""
  sensor_UV: ""
  rtfreq: 450
  delay: 15
  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 %}
  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)) }}
  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]
          ]%}
      {% 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 = 'siteid=' + station_id %} {% set _payload = _payload +
    '&siteAuthenticationKey=' + station_key %} {% set _payload = _payload +
    '&dateutc=now' %} {% set _payload = _payload + '&' if data.sensors | length
    > 0 else '' %} {% set _payload = _payload + data.sensors | join('&') %} {%
    set _payload = _payload + '&softwaretype=homeassistant' %} {{ _payload }}

Let me know if you need anything else or if itā€™s not making senseā€¦

HI @Gav_in, thanks for the code!
In my repo, I created a separate branch to change my blueprint to have WUnderground and WOW services to upload to. You can find the blueprint here.
Can you check if this works for you?

Just to be clear, I havenā€™ t read the API documentation nor have a account at WOW. I hope to look into it in the coming weeks.

If this works for you and I spend some time reading the documentation, I will merge this branch into the main branch.

1 Like

had a quick look and itā€™s throwing an errorā€¦think thereā€™s a typo in the Payload around ā€œstation_idā€ and ā€œstation_keyā€ā€¦youā€™ve renamed them in the inputs but not in the payload and thatā€™s the issue

this payload seems to be all goodā€¦

wu_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=' + wu_station_id %}
    {% set _payload = _payload + '&PASSWORD=' + wu_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 }}
  wow_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]
          ]%}
      {% 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 = 'siteid=' + wow_site_id %}
    {% set _payload = _payload + '&siteAuthenticationKey=' + wow_site_auth_key %}
    {% set _payload = _payload + '&dateutc=now' %}
    {% set _payload = _payload + '&' if data.sensors | length > 0 else '' %}
    {% set _payload = _payload + data.sensors | join('&') %}
    {% set _payload = _payload + '&softwaretype=homeassistant' %}    
    {{ _payload }}

and as a final update, checked both WU & WOW and the latest observations with new blueprint are both uploaded and liveā€¦

Hi @Gav_in,

Thanks for testing, I corrected the wrong variables and all should work now.

1 Like

yeahā€¦the updated Payload I posted worked fine and is still going strongā€¦thanks for putting it all together

Good to hear! Iā€™ll look into the specs and release it to the main branch if Iā€™ve tested it some more.

1 Like

Hi @dvandonkelaar

Thanks a lot, it works. Sorry for the long delay!

Hi @eiten,

Good to know, I merged the changes in the main branch.