Sending System Monitor integration disk usage to InfluxDB

I am using the System Monitor integration to measure hard disk usage, and am trying to send the disk values to InfluxDB.

The values correctly appear in the entities list:

I have added the following to my configuration.yaml:

influxdb:
  host: 192.168.0.65
  port: 8086
  database: homeassistant
  include:
    entities: 
      - sensor.system_monitor_disk_use
      - sensor.system_monitor_disk_usage
      - sensor.system_monitor_disk_free
  tags:
    host: hass
  component_config:
    sensor.system_monitor_disk_use:
      override_measurement: disk
      ignore_attributes:
        - device_class
        - friendly_name
        - state_class
        - unit_of_measurement
        - domain
        - entity_id
    sensor.system_monitor_disk_usage:
      override_measurement: disk
      ignore_attributes:
        - device_class
        - friendly_name
        - state_class
        - unit_of_measurement
        - domain
        - entity_id
    sensor.system_monitor_disk_free:
      override_measurement: disk
      ignore_attributes:
        - device_class
        - friendly_name
        - state_class
        - unit_of_measurement
        - domain
        - entity_id

The data is flowing into InfluxDB database, but looks like this:

> select * from disk where time>now()-2m

name: disk
time                domain entity_id                 host value
----                ------ ---------                 ---- -----
1728329549901870000 sensor system_monitor_disk_free  hass 25.3
1728329549903616000 sensor system_monitor_disk_use   hass 4.2
1728329549904819000 sensor system_monitor_disk_usage hass 14.3

There are a couple of problems with this.

  1. I would like to remove the tags “domain” and “entity_id”.
  2. All the data points are given a field name “value”. Instead I would like the data to appear like this (i.e. all three be inserted with a corresponding field name at the same timestamp):
name: disk
time                  host   used    free    usage
----                  ----   -----   ----    -----
1728327868526768000   hass   4.2     25.3    14.3

How do I acheieve this? Can it be done with a template sensor with custom attributes?

(The aim to to bring it consistently in line with some existing data from the telegraf disk input plugin.)

Anyone help with this?

I’m pretty certain this can’t be done the way you want it. HA appears to require that measurements written to InfluxDB are written as “value”, and are tagged with entity_id for uniqueness. Even for a template sensor with attributes, the sensor’s state would still be saved as “value” with the entity_id tag.

If you insist that the measurements match, your best bet may be to either install telegraf (with disk input) on your HA machine, or ship the data from HA to telegraf (on another host) for custom formatting. Telegraf has an MQTT input, so an automation could publish state changes to your broker, then telegraf can read from the broker, and send to the database. You can also configure telegraf to directly retrieve data from HA using the REST api at regular intervals. You may also be able to POST directly to InfluxDB from an automation, if you are familiar/confident enough with database commands.

Thanks, I see. Glad to know I wasn’t just missing something.

You have given lots of options for me to explore, so thank you.

Can you help me with a simple example for your REST API approach? I know how to get Telegraf to execute a bash script at regular intervals (for example, executing a curl command to GET data from a HTTP endpoint). This can be done with the exec plugin.

But I am not sure how to do things on the Home Assistant side of things. Do I need to add something to my configuration.yaml file, in order to somehow expose the sensor.system_monitor_disk_use, sensor.system_monitor_disk_free, and sensor.system_monitor_disk_usage entities?

And then how would I know what the curl command syntax needs to be in my telegraf script, in order to retrieve the data?

Thanks

Instead of the exec plugin, consider the http plugin.

First you’ll need to obtain a long term bearer token for authentication as described in the api docs.

Since you’re pulling from multiple entities, you can craft POST request to evaluate a template that returns your values in the plaintext influx protocol format.

I haven’t parsed exactly what the output template needs to look like for your desired dataset index, but hopefully the below example plus the links above will get you started.

[[inputs.http]]
  urls = "http://homeassistant.local:8123/api/template"
  method = "POST"
  headers = {“Content-Type: application/json“}
  body = ‘{"template": “disk host=hass used={{states(sensor.system_monitor_disk_use)}},free={{states(sensor.system_monitor_disk_free)}},usage={{states(sensor.system_monitor_disk_usage)}}"}’
  token = "eyJhbGc...Qssw5c"

You can test this POST request by crafting a curl command with the same parameters as described in the template example of the api docs link above.

@peterxian Thanks for this, I see now how it works.

In the end I managed to achieve it working nicely using your final suggestion. By using the shell command integration to create a service that pushes the values to the remote influxdb database. This is done by posting to the InfluxDB HTTP API endpoint.

Then finally the service is called every time interval using an automation.

This is in the configuration.yaml file:

shell_command:
  push_system_monitor_to_influxdb: "curl -i -XPOST 'http://xxx.xxx.x.xx:8086/write?db=telegraf' --data-binary 'disk,device=sda8,host=hass used={{(states('sensor.system_monitor_disk_use')|float(0) * 1024*1024*1024) |int}}i,free={{(states('sensor.system_monitor_disk_free')|float(0) * 1024*1024*1024) |int}}i,used_percent={{(states('sensor.system_monitor_disk_usage')|float(0))}}'"

(Note that I have had to convert the values back from GiB, as hard-coded by the System Monitor integration source code, back to bytes. And then to ensure the values are written as integers rather that floats you need to provide the trailing “i” characters, as required by the InfluxDB API).

This is then the automation:

alias: Push System Monitor Disk Usage to InfluxDB
description: "Use CURL to post value to remote InfluxDB instance"
trigger:
  - platform: time_pattern
    minutes: /1
condition: []
action:
  - service: shell_command.push_system_monitor_to_influxdb
    data: {}
mode: single

Thanks for all your help getting me to this solution.