How can I populate Sensors from HTTP GET parameters

I have a home weather station that will post its data to any HTTP server using GET parameters.
An example is “HTTP GET /update wind=24.9&temperature=32.7”.

I get to select the URL text to be any static string I want. In the example I used “update”. I also get to select the server so it would be cool if this server could be the HA server on port 8123.

I would like some advise on how to get this HTTP data into a Home Assistant sensor.

Who has the cleverest idea?

And yes I know I can interface to many servers on the internet to get weather data. This is not a question about that. I am looking for a clever way to translate HTTP data into HA so I do not have to use the internet.

I looked at the requirements to use RESTful sensors. I could not find any examples of sensors using the API to update home assistant. I see examples of Home Assistant using the API to interrogate sensors. Also there is an authentication requirement and specific format required of the URL.

My sensor can only publish the simple GET with parameters (shown above). I cannot change the format of the GET it uses other that the target URL.

Can anyone point me at an example of a sensor using an HTTP GET to update HA without authentication requirements?

It needs to call Home Assistant’s API with a long-lived access token (that you generate in Home Assistant). If it can’t do that, :man_shrugging:

That is the issue. It is a simple device in my home. It can generate update commands using HTTP PUT requests as shown in my OP. It cannot add any authentication headers to the command.

If anyone has any ideas please add them to this thread.

I’d roll a simple web server in Python that receives these requests then translates them into API requests. How and where that script lives is up to you: I’m running HA in a Docker container on a NAS, and I have a spare Pi on the network so a couple of opportunities there.

https://docs.python.org/3/library/http.server.html

https://pythonbasics.org/webserver/

Implementing a NodeJS server is also an option to insert/include the AUTH header.

@Troon, @EricLEdberg

For the proposed “middleman” technique, where a webserver receives data from the physical sensor and passes it on to Home Assistant, what kind of sensor integration will receive the data?

What comes to mind is the MQTT Sensor integration but I’m wondering if you thought of something else.

I’d assumed just a plain sensor via the API. As an example, here’s a bash script I run on my church’s Ubiquiti US-24-250W network switch to the public IP of my HA (via a Linode reverse proxy):

#!/bin/sh

while true
do
    export HALLT="MY_LONG_LIVED_TOKEN"
    export TEMP="`swctrl env show | head -1 | cut -d: -f2 | sed 's/\ //'`"
    export FAN="`swctrl env show | grep "Fan-1" | tr -s ' ' | cut -d\  -f3`"
    export POE="`swctrl poe show | tr -s ' ' |grep "\ On\ " | cut -d\  -f2,10 | sed 's/\ /\":\"/' | sed 's/^/\"/' | sed 's/$/\",/' | head -c -2`"
    export TS="`date -Iseconds`"
    export LD1="`cat /proc/loadavg | cut -d\  -f1`"
    export LD5="`cat /proc/loadavg | cut -d\  -f2`"

    curl -X POST -H "Authorization: Bearer $HALLT" -H "Content-Type: application/json" \
         -d "{\"state\": \"$TEMP\", \"attributes\": \
             {\"fan\": \"$FAN\", \
              \"LD1\": \"$LD1\", \
              \"LD5\": \"$LD5\", \
              \"unit_of_measurement\": \"°C\", \
              \"device_class\": \"temperature\", \
              \"friendly_name\": \"church network switch\", \
              \"updated\": \"$TS\", \
              \"POE\": {$POE} }}" \
         https://MY_DOMAIN/api/states/sensor.church_switch

    sleep 300
done

That creates and updates the entity sensor.church_switch (not the actual name I use, redacted for anonymity) with a bunch of attributes every 5 minutes:

As I understand it, that’s not using any particular integration?

Correct me if I’m wrong but any entity created that way exists only until Home Assistant is restarted. After a restart, it’s gone until the next time (your script) creates it again during a scheduled update (5 minutes in your example).

That’s also my understanding, yes. Same as with sensors created via AppDaemon like my bin collection sensors.

Obviously, historical values are retained, so it’s only the short window after restart where there is no data. I can live with that for these examples.

If pbix accepts the idea of using a webserver as a middleman, then it can also be implemented in Node-Red and the data forwarded to Home Assistant via either MQTT or HTTP. If pbix doesn’t already use Node-Red (or MQTT), and isn’t interested in adopting it, then what you suggested, namely a simple python-based webserver plus shell script, is probably the next easiest solution.


FWIW, I threw this together:

Screenshot from 2021-06-14 10-55-36

When you execute an URL like this:

http://your-server:1880/endpoint/weatherupdate?wind=24.9&temperature=32.7

it responds with “Received” and publishes the data as a JSON payload to the topic weather.

Screenshot from MQTT Explorer:

Screenshot from 2021-06-14 11-15-26

Published as a retained message, it’s now available for use with an MQTT Sensor even after Home Assistant is restarted.

sensor:
  - platform: mqtt
    name: Outdoor Temperature
    state_topic: weather
    value_template: '{{ value_json.temperature }}'
    device_class: temperature
    unit_of_measurement: '°C'

  - platform: mqtt
    name: Outdoor Wind Speed
    state_topic: weather
    value_template: '{{ value_json.wind }}'
    unit_of_measurement: 'km/h'

Alternately, the Node-Red flow can HTTP POST the data in the same manner as shown in your example.

1 Like

Thanks for the discussion. I too have thought about the HTTP->MQTT bridge idea which could be implemented on something like Node RED or my router which runs OpenWRT.

But I have been thinking on the fact that what is needed is much simpler than a webserver. A wonder if a Python script running on HA could do this directly. The script would just listen on a configurable TCP port and when it gets the string it parses the parameters, updates the sensors and returns an “OK” response to the sender. Could be developed as a generic “HTTP GET/POST” integration and possibly used by others.

That is pretty much the definition of a web server. The easiest way to make that would be using the http.server module I linked above.

Having spent untold hours helping others with Home Assistant over the past 2.5 years, your requirement is the first I’ve encountered on this forum. If you want to develop and share a custom integration for it, go ahead. However, I don’t imagine there will be a significant demand for it, especially when it’s so easy to put together functional alternatives (shown above).

Honestly, the most time-consuming part of creating that flow was discovering the Node-Red Add-on maps the “HTTP In” node to port 1880 (and URLs begin with /endpoint). Once that was sorted, the remainder was trivial.

Thanks Taras and Troon for the expert advice. It helps keep me from digging in the wrong rabbit hole.
Give me some time to experiment and I will post my results.