Import InfluxDB data as sensor in Home Assistant

I’ve struggeled some time now with Influx and Home Assistant. There a lots of tutorials explaining how to get Home Assistant data into an Influx database. But vice versa, getting data out of an Influx database into Home Assistant is just explained in the HA integrations page. But unfortunately I could not make it work directly struggeling with the syntax. So I will just share my experiences, hopefully it might help someone.

Why getting InfluxDB data into HA? Pretty easy. I have a lot of data - like e.g. FreeNAS or a power meter - that I already installed before I started with HA. So I have already set up a good way (e.g. FreeNAS with the Graphite option) to push data into a database. Some data - like how much space is left on my storage or how hot are disks running - I can pretty easy watch in Grafana with also historic values. But as HA is for me the “single pane of glass” for all my stuff at home, I wanted to see just the current temperature, current power consumption (coming from my power meter) and not integrate another way to get data in HA to just push it to InfluxDB, what already works.

So first: configuration.yaml needs to be edited.

influxdb:
host: xxx.xxx.xxx.xxx
database: database-name
exclude:
entity_globs: “*”

If your database doesn’t run on the same host, you definitely need to enter the InfluxDB host as target for data that would come from HA. You also need to add a database, when you don’t have a home-assistant database in your InfluxDB. After that, just exclude all data for writing to the Influx.

Then you need to create a sensor for the data you want to query from Influx:

sensor:
platform: influxdb
host: xxx.xxx.xxx.xxx
queries:
- name: PowerConsumption
unit_of_measurement: W
value_template: ‘{{ value | round(1) }}’
where: ‘“meter” = ‘‘Overall Power’’’
measurement: ‘energy’
field: ‘“Power Sum”’
group_function: last
database: db_meter_test

Here you can see what needs to be enter. The query in Influx looks like this:

“SELECT last(“Power Sum”) AS “Power Sum” FROM “energy” WHERE (“meter” = ‘Overall Power’) AND time >= now() - 1h GROUP BY time(2s)”

In fact there are some parts you can’t really translate into HA. Here you can see, what really is needed and can be used for HA:

SELECT last(“Power Sum”) FROM “energy” WHERE (“meter” = ‘Overall Power’) AND time >= now()

I skipped the “AS” clause as well as “1h GROUP BY time(2s)”

The other case, where I struggled, was a query with missing “where” clause:

SELECT last(“value”) FROM “servers.freenas.disktemp-ada0.temperature” WHERE time >= now() - 6h

This also will skip some query parts to look like this:

SELECT last(“value”) FROM “servers.freenas.disktemp-ada0.temperature” WHERE time < now()

As you can see, the “where” clause has another query regarding “>=” what changed to “<”. The reason for that might caused by a different time on InfluxDB and HA, even though a NTP server is running. But I could not find the right reason for this issue. So the sensor looks like this:

- name: ada0_temperature
  value_template: '{{ value }}'
  where: 'time < now()'
  measurement: '"servers.freenas.disktemp-ada0.temperature"'
  field: value
  group_function: last
  database: graphite

As you can see, there needs to be something in the “where” variabel, otherwise it will not work at all.

I hope, this can help some of you to reduce the time to implement.

3 Likes

Thank you for this example. Helped me a lot on the way. Here is my working code. I had to change the quotes to make it work.

In file sensor.yaml

- platform: influxdb
  host: !secret influxIP
  username: homeassistant
  password: !secret influxpw
  queries:
    - name: AirConditionPowerConsumption
      unit_of_measurement: W
      value_template: "{{ value | round(1) }}"
      where: '"device" = ''IotaWatt'''
      measurement: iotawatt.autogen.kurs12
      field: "value"
      group_function: last
      database: iotawatt

The query I had in chronograf/Influxdb

SELECT last("value") AS "value" FROM "iotawatt"."autogen"."kurs12" WHERE time > :dashboardTime: AND "device"='IotaWatt'
3 Likes

I cannot make this work - and my query is very simple:

SELECT “Run Time” FROM “runTime” WHERE time >= now() - 7d and time <= now()

I have setup influxdb near the top of the config.yaml file like this:

#Influx connection
influxdb:
host: 192.168.1.xxx
verify_ssl: false
exclude:
entity_globs: “*”

and created a sensor like this:

  • platform: influxdb
    host: 192.168.1.xxx
    queries:
    • name: SepticPumpRunTime
      field: Run Time
      where: ‘time > now() - 1d’
      #group_function: last
      database: Pump_Monitor
      measurement: ‘“runTime”’

I realize I tweaked the where function…but I have tried a ton of different combos based on a couple threads I have found in here but with no results. My influx db is on another pi in my house and I would like to populate a chart in lovelace from existing data. I am willing to change approaches if required.

When I look at the logs of my lnfux container I can see it always returns 400 which I assume is the http code for bad request.

Anyone have any ideas?

Thanks for this! I used this as a skeleton to bring in my electric and gas consumption from [1]. I adapted this for use with influxdb2 and flux. It pulls the last value in the most recent hour.

The value_template entries are partly cosmetic - handling them as floats means there’s too many decimals places displayed. But my electric meter sends deciwatt-hour readings (instead of watt-hour or kilowatt-hour) even though it’s screen reads kilowatt-hours. Go figure.

sensor:
  - platform: influxdb
    api_version: 2
    host: <influx host>
    port: <influx port>
    token: <influx token>
    organization: <influx organization id>
    bucket: rtlamr
    queries_flux:
      - name: "Electric meter reading"
        range_start: "-1h"
        unit_of_measurement: kWh
        value_template: "{{ (value|float / 100.0)|round(2) }}"
        query: >
          filter(fn: (r) => r["_measurement"] == "utilities")
          |> filter(fn: (r) => r["_field"] == "consumption")
          |> filter(fn: (r) => r["endpoint_id"] == <endpoint id>)
          |> filter(fn: (r) => r["endpoint_type"] == "7")
          |> filter(fn: (r) => r["msg_type"] == "cumulative")
          |> filter(fn: (r) => r["protocol"] == "IDM")
          |> last(column: "_value")
          |> keep(columns: ["_value"])
      - name: "Gas meter reading"
        range_start: "-1h"
        unit_of_measurement: ft³
        value_template: "{{ value|float|round(2) }}"
        query: >
          filter(fn: (r) => r["_measurement"] == "utilities")
          |> filter(fn: (r) => r["_field"] == "consumption")
          |> filter(fn: (r) => r["endpoint_id"] == <endpoint id>)
          |> filter(fn: (r) => r["endpoint_type"] == "12")
          |> filter(fn: (r) => r["msg_type"] == "cumulative")
          |> filter(fn: (r) => r["protocol"] == "SCM")
          |> last(column: "_value")
          |> keep(columns: ["_value"])

[1] - GitHub - bemasher/rtlamr-collect: Data aggregation for rtlamr.

I got it working with the following setup and will post in case it helps.

influxdb:
  exclude:
    entity_globs: “*”


sensor:
#influx sensors
  - platform: influxdb
    host: 192.xxx.x.xxx
    queries:
      - name: test_temp
        field: Temperature
        where: 'time > now() - 7d'
        group_function: last
        database: YardWeather
        measurement: '"YardWeather"."18months"."WSReportedTemp"'
      - name: influx_sp_run_time
        field: '"Run Time"'
        where: 'time > now() - 7d'
        group_function: last
        database: Pump_Monitor
        measurement: '"Pump_Monitor"."autogen"."runTime"'

Hi guys, I spent a few hours to get it work.

  1. there is BUG in the documentation, in their example, there is missing MINUS before PLATFORM in the sensor definition.
  2. Your configuration is correct but will create error logs in log file, because the first part with INFLUXDB definition is missing and it’s trying to connect to localhost/home-asistant.

Proper configuration:

# InfluxDB - read data from InfluxDB as sensor in HA
influxdb:
  host: influxdb20.openpli
  port: 8086
  ssl: true
  verify_ssl: false
  username: admin
  password: XXX
  database: telegraf
  exclude:
    entity_globs: "*"
sensor:
  - platform: influxdb
    api_version: 1
    host: influxdb20.openpli
    port: 8086
    ssl: true
    verify_ssl: false
    username: admin
    password: XXX
    queries:
      - name: influx.Outside Temp
        unit_of_measurement: °C
        value_template: "{{ value | round(2) }}"
        group_function: last
        where: '"enviro" = ''sensors/temperature'''
        measurement: '"mqtt_consumer"'
        field: value
        database: telegraf

Can you help me making a sensor that reads the data out of influxdb?

@kUMters

I’m hoping you may be able to enlighten me on this. I have two different databases within the same influxdb instance. One of them is the database for HA that was created when installing the influxdb add-on/integration. I pointed it toward an existing influxdb install I had. I also have a db in that same influxdb instance that contains other sensor data. Is it possible to read data from the second database as well so I can use that as sensor data too?

I would also like to share my findings, as it is relatively hard to gather the information - Topic:

Create a Home Assistant Sensor with imported values from InfluxDB2

Official Documentation
There is only a single documentation for InfluxDB integration covering writing of data to a database and also importing data from a database. The later is covered in the section “Sensor”.
https://www.home-assistant.io/integrations/influxdb/

Sensor
Although - as covered in the documentation - you do need an (empty) “influxdb” section, you need to specify all influxdb parameters in the “sensor” section - so reading from a different bucket & having a seperate read token can be realised easily.

queries_flux
This part of the configuration is hard to figure out. Here are some tips:

  • group_function: The documentation only provides an example with average, but to simply get the current value, the group_function last can be used - without any time reference.
  • query: The InfluxDB2 query can be explored and built interactively in the web-UI of the used influxDB instance. And you actually don’t need an last() or keep() call, you just have to apply filters that only a single value is left and that will be used by homeassistant.
  • unique_id: When the sensor is created with a name only, it can be viewed in Home Assitant, but it can not be modified through the UI. To enable that, the variable unique_id must be provided. I assume that the format does not matter at all. I used this website to generate an Version 4 UUID:
    https://www.uuidgenerator.net/version4

Putting all things together, my configuration.yaml now loooks like this:

# write home assistant sensors to influxdb
influxdb:
  api_version: 2
  ssl: false
  host: influxdb
  port: 8086
  token: <write-token-to-homeassistant-bucket>
  organization: homelab
  bucket: homeassistant
  precision: s # use *second* precision to save data, default ns
  measurement_attr: domain__device_class # Note: only one of 3 possible values
  # Alternative: use "override_measurement" to use the same measurement for all sensors
  tags_attributes:
    - friendly_name
    - unit_of_measurement
    - device_class
  ignore_attributes:
    - state_class
    - icon
  include: 
    entities:
      - sensor.my_sensor1
      - sensor.my_sensor2


# import influxdb values as home assistant sensor
sensor:
  - platform: influxdb
    api_version: 2
    ssl: false
    host: influxdb
    port: 8086
    token: <read-token-to-measurement-bucket>
    organization: homelab
    bucket: measurement
    queries_flux:
      - name: "My Measurement Sensor"
        unique_id: 8b64c4ae-f855-4af5-8a06-a7db99639b36 # !!! generate a new one: https://www.uuidgenerator.net/version4
        unit_of_measurement: "apples/day"
        # simply build your own query via influxDB2 web-UI
        query: >
          filter(fn: (r) => r["_measurement"] == "my-measurement" and r["_field"] == "apples")
        group_function: last

Further resources I found:
A reddit guide on using the InfluxDB2 web-UI to build the query:
https://www.reddit.com/r/homeassistant/comments/nhw7fk/my_experience_with_converting_from_influxdb_v1x/

Some more confusing documentation about the InfluxDB integration:

Hello,

my query looks like

SELECT mean("rx_bytes-r") AS "mean_rx_bytes-r" FROM "HomeAssistant_xaquib666"."autogen"."usg_wan_ports" WHERE time > :dashboardTime: AND time < :upperDashboardTime: GROUP BY time(:interval:) FILL(null)

I have defined my sensor like the following.

- platform: influxdb
  host: !secret influxdb_host
  port: !secret influxdb_port
  database: !secret influxdb_database
  username: !secret influxdb_username
  password: !secret influxdb_password
  queries:
    - name: UDM_Download_Speed
      where: '"HomeAssistant_xaquib666"."autogen"."usg_wan_ports"'
      field: '"rx_bytes-r"'
      measurement: '"usg_wan_ports"'
      group_function: last
      database: !secret influxdb_database

The query is working.

But I am getting unknown values.

Can anyone please help to identify where is my mistake?

Thanks!

Highly non expert here.
What about a unit of measurement. I am using flux, but I imagine the same concept applies

queries_flux:
      - name: "nnhdd1-4_disk_temp"
        unit_of_measurement: "degC"
        query: >
          filter(fn: (r) => r["_measurement"] == "DiskTemp" and r["_field"] == "value" and r["component"] == "NNHDD1-4")
        group_function: last

I could be way off base here!!!

Hello everyone,

I’m currently facing an issue that’s been causing me some frustration. I can’t seem to create an InfluxDB query for a sensor. The database is functional, and the measurement “sensor.tagesverbrauch” exists with up-to-date values. When I perform a query in Grafana (which works), I see something like this:

SELECT mean("value") FROM "autogen"."sensor.tagesverbrauch" WHERE $timeFilter GROUP BY time($__interval) fill(null)

The database and Influx are also set up in Home Assistant, where Home Assistant stores various sensor values in InfluxDB.

Here’s the configuration for the sensor:

sensor:
  - platform: influxdb
    host: 192.168.xxx.xxx
    port: 8086
    username: user
    password: password
    queries:
      - name: xxx_test
        #unique_id: xxxtest
        #unit_of_measurement: kWh
        #value_template: '{{ value | round(2) }}'
        group_function: 'time($__interval) fill(null)'
        where: '$timeFilter'
        measurement: '"autogen"."sensor.tagesverbrauch"'
        field: value
        database: homeassistant

The problem is that the sensor doesn’t appear among the entities, and there are no error messages. Do you have any ideas? I’ve spent hours trying various configurations, and even chatGPT couldn’t provide any hints. Do you know of an AI better suited for this type of issue?

Best regards,
ibcm123

1 Like

I managed to solve it on my own now. Here’s the solution:

sensor:
  - platform: influxdb
    host: 192.168.xxx.xxx
    port: 8086
    username: user
    password: password
    queries:
      - name: xxx_test
        unit_of_measurement: kWh
        value_template: '{{ value }}'
        group_function: max
        measurement: '"autogen"."sensor.tagesverbrauch"'
        field: "value"
        where: 'time < now()'
        database: homeassistant

This is just a simple example. Now, I’m still looking for a way to also retrieve the timestamp from InfluxDB. I want to get a specific value along with its timestamp. So far, I haven’t found anything about it on the web, but it can’t be impossible, can it?

I would appreciate any help. In the Influx shell, a timestamp is always provided when I make a query. Unfortunately, no example seems to address this…

Best regards,
ibcm123

I tried the same thing and came to the conclusion that this all does not work, by definition. A sensor can only have one single state, not a history. The docs read:

The influxdb sensor allows you to use values from an InfluxDB database to populate a sensor state.

“A” sensor “state”. Meaning you cannot create a history within a sensor. The sensor creates history itself via HA’s history function. AFAIK there is no function yet to retrieve history from other sources that the in-built HA history that itself writes the influxdb long term history.

You’ll find this in the logs, which is pretty self-explenatory:

Query returned multiple results, only value from first one is shown: from(bucket:"home_assistant") |> range(start: -52w, stop: now()) |> filter(fn: (r) => r["entity_id"] == "**redacted**") |> filter(fn: (r) => r["_field"] == "value") |> filter(fn: (r) => r["_measurement"] == "kg") |> keep(columns: ["_value", "_time"]) |> yield(name: "last") |> limit(n: 1).

I’ve noticed that the update interval for the HA sensor (and therefore the interval over which the ‘group function’ operates) seems to be 1 minute. For certain sensors this is insufficient, both for reporting and if you wanted to take an immediate action.

I have a path to integrate the data with HA directly which will be more reliable anyway… but… It would be nice to have the option.

I am trying a different way to implement an InfluxDB size sensor into home assistant, but something doesn’t work. Normally you can check the size of the InfluxDB on disk with the command

du -sh /var/lib/influxdb/

This generates an output like:

472K    /var/lib/influxdb/

Now with a small addition the command looks like

sudo du -s /var/lib/influxdb/ | cut -f1

generating an output like

472

which is the file size of the entire InfluxDB database on disk in kilo bytes. I’d like to transform this number into a sensor in HASS. I have tried the following addition in my configuration.yaml:

    - sensor:
        name:  influxdb_size
        command: "sudo du -s /var/lib/influxdb/ | cut -f1"
        unit_of_measurement: "KB"

And here come the problems:

If I use this command with sudo, HA log shows that HA is asking for the sudo password (which I do not know in HA core virtual environment) and then this results in the following error message:

2023-11-24 22:25:28.099 ERROR (SyncWorker_5) [homeassistant.components.command_line.utils] Timeout for command: sudo du -s /var/lib/influxdb/ | cut -f1

and if I use this command without sudo, this results in the following error message:

du: cannot read directory '/var/lib/influxdb/data/home_assistant': Permission denied
du: cannot read directory '/var/lib/influxdb/wal': Permission denied

Is there a way to get this command to work? Thanks for any hints.

I have found the solution to this question here.

Now I configured a new sensor in configuration.yaml as follows:

    - sensor:
        name: influxdb_size
        unique_id: influxdb_size
        command: "echo /password/ | sudo -S du -s /var/lib/influxdb | cut -f1"
        unit_of_measurement: "kB"
        device_class: data_size
        scan_interval: 3600
        icon: mdi:file

/password/ is the password that you assigned to your homeassistant user for running with sudo!

This sensor is the readable in HA:

For me this is a good & practical way to monitor the influxdb size in HA.

And - to add to that - I’m also monitoring home_assistant_v2_db_size with a similar sensor:

    - sensor:
        name: home_assistant_v2_db_size
        unique_id: home_assistant_v2_db_size
        command: "du /home/homeassistant/.homeassistant/home-assistant_v2.db | cut -f1"
        unit_of_measurement: "kB"
        device_class: data_size
        scan_interval: 3600
        icon: mdi:file

I like this more than the included “file size” integration as I can set the sensor to update only once per hour, which is more than sufficient for me.

Nice monitoring of DB sizes in HA:

I am able to solve it as below for query

SELECT mean(“Consumption”) AS “mean_Consumption” FROM “homeassistant”.“autogen”.“thames_daily_water_usage” WHERE time > :dashboardTime: AND time < :upperDashboardTime: AND “ticker”=‘dailywaterusage’ GROUP BY time(:interval:) FILL(null)

- platform: influxdb  
  host: 192.168.xx.xx  # Replace with the host where InfluxDB is running
  port: 8086       # Default InfluxDB port
  username: xxxx
  password: xxx
  database: homeassistant
  queries:
    - name: "Thames_Daily_Water_Consumption"
      unit_of_measurement: "L"  # Update with appropriate unit
      value_template: '{{ value_json }}'
      group_function: last
      where: "ticker='dailywaterusage'"
      measurement:  "homeassistant.autogen.thames_daily_water_usage" 
      field: "Consumption"