FreeNAS Stat Monitor

I was running FreeNAS in a VM for testing and now upgraded to TrueNAS 12 beta. It seems like the “old” api v1.0 is no longer available. There is now a v2.0 api. I already played around with it, but it seems like there are no “pct used” values any more. Version flag also changed. So be aware if you upgrade. Might that they will add v1.0 api in the TrueNAS final release for compatibility, what I really hope for.

1 Like

@Shogun1978 Thanks for the heads up. I haven’t played around with the beta yet…

@Limych’s solution should still work with TruNAS though. It doesn’t rely on FreeNAS’s API. It’s pretty slick. FreeNAS Stat Monitor

1 Like

@gremblin: you have installed HA in a FreeNAS jail? Or as add-on? So you can grab the values locally?

No, I am running HA on a raspberry pi 4. The values are pulled over the local network using FreeNAS’s API.

1 Like

If you had HA in a jail, you still wouldn’t be able to pull values locally. The jail prevents you from reading data from your main FreeNAS. If you installed HA in your main FreeNAS install area, that might be possible, but it is not recommended to touch your main FreeNAS install base.

I see there are a few different ways to pull information from our NAS

  1. Using the API
  2. Commands over ssh
  3. Using @Limych Solution
  4. Using SNMP Monitoring

I just started making some sensors to test using the 2.0 API on TrueNAS

image

It appears all the information I could want is available using the new API, however, considering there are other methods to retrieve this data, I’m wondering – Is using the API the best (or preferred) way to go??

I don’t want to spend a bunch a time making rest sensors only to find out later, I should have done something else :smile: – Thanks

1 Like

I’d prefer to use the API to poll information from FreeNAS instead of pushing it to HA.

A push method will prevent HA from attempting to pull if FreeNAS is down, but I think it is a matter of can you get all of the data that you want with your chosen method and which method are you most comfortable with.

Does anyone else have more experience with getting sensor information of FreeNas via REST APi 2.0?
I built few sensors with 1.0 and I´m not fully satisfied with, so I´m considering to realize that with 2.0.

But honestly I don´t know how to start. Even I don´t know how to see information via webbrower directly on the NAS: I am use to open
http://IP -OF-YOUR-FREENAS/api/v1.0/storage/volume/VOLUME-NAME/?format=json but with 2.0 it doesn´t work.

@troy: Maybe you could push me in the right direction.

From the beginning, here’s what I got so far – for example first get a list of the reporting graphs, then second two commands are each ways of pulling the cputemp data, the start and end times are an epoch timestamp.

curl -X GET "http://localhost/api/v2.0/reporting/graphs" -H "accept: */*" --user 'root:password' | jq
curl -X POST "http://localhost/api/v2.0/reporting/get_data" -H "accept: */*" -H "Content-Type: application/json" -d '{"graphs":[{"name":"cputemp"}],"reporting_query":{"start":"1596338230","end":"1596338231","aggregate":true}}' --user 'root:password'
curl -X POST "http://localhost/api/v2.0/reporting/get_data" -H "accept: */*" -H "Content-Type: application/json" -d '{"graphs":[{"name":"cputemp"}],"reporting_query":{"unit":"HOUR","page":0,"aggregate":true}}' --user 'root:password'

Here’s how far I got making a package file using the – REST sensor

## FreeNAS / TrueNAS Core example sensors - RESTful API ver 2.0
homeassistant:
  customize:
    sensor.nas_info:
      icon: mdi:server-network
      hidden: true


sensor:
  ## system information
  - platform: rest
    name: NAS_info
    resource: http://10.10.1.10/api/v2.0/system/info
    headers:
      Authorization: !secret tn_bearer_token
      Content-Type: application/json
      User-Agent: Home Assistant
    scan_interval: 3600
    value_template: '{{ value_json.uptime }}'
    json_attributes:
      - uptime
      - version
      - model
      - cores

  ## template sensors can extract state_attr
  - platform: template
    sensors:
      ## NAS Uptime
      nas_uptime:
        friendly_name: "Uptime"
        value_template: "{{ state_attr('sensor.nas_info', 'uptime') }}"
        entity_id: sensor.nas_info
      ## NAS Version
      nas_version:
        friendly_name: "Version"
        value_template: "{{ state_attr('sensor.nas_info', 'version') }}"
        entity_id: sensor.nas_info
      ## CPU model
      nas_cpu_model:
        friendly_name: "Model"
        value_template: "{{ state_attr('sensor.nas_info', 'model') }}"
        entity_id: sensor.nas_info
      ## CPU num of cores
      nas_cpu_cores:
        friendly_name: "Cores"
        value_template: "{{ state_attr('sensor.nas_info', 'cores') }}"

        
  ## check status of mosquitto plugin
  - platform: rest
    name: mosquitto
    resource: http://10.10.1.10/api/v2.0/plugin/id/mosquitto
    headers:
      Authorization: !secret tn_bearer_token
      Content-Type: application/json
      User-Agent: Home Assistant
    scan_interval: 3600
    json_attributes:
      - name
      - state
    value_template: '{{ value_json.state }}'
    
    
    ## cpu temp version 2
    ## remember - set `cores=$num` in the value_template
  - platform: rest
    name: nas_v2_cpu_temp
    resource: http://10.10.1.10/api/v2.0/reporting/get_data
    headers:
      Authorization: !secret tn_bearer_token
      Content-Type: application/json
      User-Agent: Home Assistant
    device_class: temperature
    unit_of_measurement: '°C'
    scan_interval: 60
    method: POST
    payload: >-
      {
        "graphs":[{"name":"cpu"},{"name":"cputemp"}],
        "reporting_query":{"unit":"HOUR","page":0,"aggregate":true}
      }
    json_attributes_path: "$.[0]"
    json_attributes:
      - aggregations
    value_template: >-
      {% set tn = namespace(temp=0, cores=8) %}
      {% for core in range(0, tn.cores) %}
        {% set tn.temp = tn.temp + value_json[1].data[358][core] %}
      {% endfor %}
      {{ "%.1f"% (tn.temp / tn.cores) }}


## Pools
  - platform: rest
    name: nas_nvme_pool
    resource: http://10.10.1.10/api/v2.0/pool/id/19
    headers:
      Authorization: !secret tn_bearer_token
      Content-Type: application/json
      User-Agent: Home Assistant
    scan_interval: 3600
    json_attributes:
      - name
      - scan
      - topology
      - is_decrypted
    value_template: '{{ value_json.status }}'

It was about this point I started to realize with the amount of api calls and data parsing required, using the REST sensor alone was gonna be a bit of work. For this, and also weighed heavily by other off-topic ( ideas for the TrueNAS plugin and needing to replace G-Music Player integration with Y-Tube Music ) reasons, I decided to just go for the custom integration even though it’s likely to be a complete uphill battle :smile: It’s pretty rough at this point but I think with a little more time, I’ll at least have a basic sensor that pulls in some parsed data from the api, making it easier to break out with template sensors. I have a lot of ideas but I’m trying to stay focused on some basic ground work for now.

1 Like

well, this is great. Actually I mostly do understand what you´re doing there :slight_smile:

But I´ve got one big issue: WIth

 json_attributes:
    - uptime
    - version
    - model
    - cores

you´re getting the needed values, but how can I see what possible values also available? in API 1.0. I was able to see all information with one (unformated) website. Then I simply used each parameter needed. In 2.0 I´m not able to get any information. On http://freenasip/api/docs/ or http://freenasip/api/v2.0/ I always get 401 unauthorized message. I typed your curl commands with my user, that worked

I never used the 1.0 API so I’m unable to relate the differences.

Same here, I didn’t much time trouble-shooting though, I figure it’s missing login credentials but I don’t see a way to edit / add those from the web page view.

I’m just taking the primitive approach. I have the api page open for reference, and I’ve just been working my way through bit by bit using curl and piping through jq to help make results easier read in the terminal.

 json_attributes:
    - uptime
    - version
    - model
    - cores

These attr came from system/info

curl -X GET "http://localhost/api/v2.0/system/info" -H "accept: */*" --user 'root:password' | jq
{
  "version": "TrueNAS-12.0-BETA",
  "buildtime": [
    {
      "$date": 1593538042000
    }
  ],
  "hostname": "truenas.local",
  "physmem": 34081218560,
  "model": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz",
  "cores": 8,
  "loadavg": [
    0.154296875,
    0.21337890625,
    0.21728515625
  ],
  "uptime": "10:02AM  up 12 days, 18 hrs",
  "uptime_seconds": 1101606.12825346,
  "system_serial": "0123456789",
  "system_product": "Super Server",
  "system_product_version": "0123456789",
  "license": null,
  "boottime": {
    "$date": 1596297744000
  },
  "datetime": {
    "$date": 1597413750128
  },
  "birthday": {
    "$date": 1593886329149
  },
  "timezone": "America/New_York",
  "system_manufacturer": "Supermicro",
  "ecc_memory": true
}
1 Like

Sorry for my late answer. I didn’t have time to take care of things over the weekend.
Too bad, with the web interface it was very convenient. OK, thanks to your tip on the command line, I’m able to use the API documentation to get the relevant information. It’s a bit of work in the beginning, but the main thing is that it works. I could only go via the API key because I can’t create an API key. I think this is because I’m still on FreeNas 11.3.4 and I can’t create an API Key.

Thanks for your support!

1 Like

@troy, have you had a chance to play around more with the 2.0 API? Anyone else?

I can’t find a simple way to pull the available space in a pool, ideally just as a percentage free or something like that. The old sensor had a used_pct attribute.

Also, I don’t know how to properly handle the alerts. Right now I’m using:

- platform: rest
  name: tn_alert_level
  resource: http://192.168.1.4/api/v2.0/alert/list
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  scan_interval: 300
  json_attributes:
    - level
    - formatted
  value_template: >
    {% if value_json is defined %}
      {{ value_json[0].level }}
    {% else %}
      {{ "None" }}
    {% endif %}
- platform: template
  sensors:
    ## Alert message
    tn_alert_message:
      friendly_name: "Alert Message"
      value_template: "{{ state_attr('sensor.tn_alert_level', 'formatted') }}"

But I get errors if there are no alerts despite the conditional.

Hi @reven

Sorry, not yet. I have not been very motivated on the computer these last few weeks :disappointed:. I hope to be back at it soon though.

This is what I have to get used allocation in a pool.

- platform: rest
  name: Nas Storage
  resource: http://192.168.1.180/api/v2.0/pool/id/1
  headers:
    Authorization: mytoken
    User-Agent: Home Assistant
    Content-Type: application/json
  value_template: '{{ value_json["status"] }}'
  json_attributes_path: '$.topology.data[0].stats'
  json_attributes:
    - allocated
    - size
  scan_interval: 1800
- platform: template
  sensors:
    nas_storage_usage:
      friendly_name: "Nas Storage Usage"
      value_template: ' {{ (state_attr("sensor.nas_st\
orage", "allocated") / state_attr("sensor.nas_storage",\
 "size") * 100) | round(1) }} '
      unit_of_measurement: "%"
3 Likes

Thanks @MatthewFlamm!

So with all the bits and pieces that everyone has posted here and elsewhere, these are my TrueNAS sensors that all work with the 2.0 API and don’t rely on scripts, and this is my monitor page:

Hope it’s useful to someone and feel free to suggest improvements.

# TrueNAS sensors

# All of the sensors have been ported to use the v2.0 API.

# Current sensors:
# rest:
#   tn_info (uptime, version, model, cores)
#   tn_cpu_temp
#   tn_alert_level *
#   tn_pool
#   tn_disk_temp
# template:
#   tn_uptime_seconds
#   tn_uptime
#   tn_pool_pct_used
#   tn_version
#   tn_cpu_model
#   tn_cpu_cores
#   tn_alert_message
#   tn_ada0_temperature
#   tn_ada1_temperature
#   tn_ada2_temperature

# General info
- platform: rest
  name: tn_info
  resource: http://192.168.1.4/api/v2.0/system/info
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  scan_interval: 3600
  value_template: '{{ value_json.uptime }}'
  json_attributes:
    - uptime_seconds
    - version
    - model
    - cores

## template sensors that extract state_attr
- platform: template
  sensors:
    ## NAS Uptime seconds
    tn_uptime_seconds:
      friendly_name: "Uptime seconds"
      value_template: "{{ state_attr('sensor.tn_info', 'uptime_seconds') }}"
    ## NAS Uptime seconds nice
    tn_uptime:
      friendly_name: "Uptime"
      value_template: >-
        {%- set uptime  = states.sensor.tn_uptime_seconds.state | round -%}
        {%- set sep     = ', ' -%}
        {%- set TIME_MAP = {
            'week': (uptime / 10080) % 10080,
             'day': (uptime / 1440) % 7,
            'hour': (uptime / 60) % 24,
          'minute': (uptime % 60)
        }
        -%}

        {%- for unit, duration in TIME_MAP.items() if duration >= 1 -%}
          {%- if not loop.first -%}
            {{ sep }}
          {%- endif -%}

          {{ (duration | string).split('.')[0] }} {{ unit }}

          {%- if duration >= 2 -%}
            s
          {%- endif -%}
        {%- endfor -%}

        {%- if uptime < 1 -%}
          just now
        {%- endif -%}
    ## NAS Version
    tn_version:
      friendly_name: "Version"
      value_template: "{{ state_attr('sensor.tn_info', 'version') }}"
    ## CPU model
    tn_cpu_model:
      friendly_name: "Model"
      value_template: "{{ state_attr('sensor.tn_info', 'model') }}"
    ## CPU num of cores
    tn_cpu_cores:
      friendly_name: "Cores"
      value_template: "{{ state_attr('sensor.tn_info', 'cores') }}"

## cpu temp version 2
## remember - set `cores=$num` in the value_template
- platform: rest
  name: tn_cpu_temp
  resource: http://192.168.1.4/api/v2.0/reporting/get_data
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  device_class: temperature
  unit_of_measurement: '°C'
  scan_interval: 60
  method: POST
  payload: >-
    {
      "graphs":[{"name":"cpu"},{"name":"cputemp"}],
      "reporting_query":{"unit":"HOUR","page":0,"aggregate":true}
    }
  json_attributes_path: "$.[0]"
  json_attributes:
    - aggregations
  value_template: >-
    {% set tn = namespace(temp=0, cores=4) %}
    {% for core in range(0, tn.cores) %}
    {% set tn.temp = tn.temp + value_json[1].data[358][core] %}
    {% endfor %}
    {{ "%.1f"% (tn.temp / tn.cores) }}

## Alerts. Error if response is empty.
- platform: rest
  name: tn_alert_level
  resource: http://192.168.1.4/api/v2.0/alert/list
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  scan_interval: 300
  json_attributes:
    - level
    - formatted
  value_template: >
    {% if value_json is defined %}
      {{ value_json[0].level }}
    {% else %}
      {{ "None" }}
    {% endif %}
- platform: template
  sensors:
    ## Alert message
    tn_alert_message:
      friendly_name: "Alert Message"
      value_template: "{{ state_attr('sensor.tn_alert_level', 'formatted') }}"

# Disk temps
- platform: rest
  name: tn_disk_temp
  method: POST
  resource: http://192.168.1.4/api/v2.0/disk/temperatures
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  scan_interval: 300
  payload: '{"names":["ada0","ada1","ada2"]}'
  json_attributes:
    - ada0
    - ada1
    - ada2
- platform: template
  sensors:
    tn_ada0_temperature:
      unit_of_measurement: '°C'
      value_template: '{{ state_attr("sensor.tn_disk_temp", "ada0") }}'
    tn_ada1_temperature:
      unit_of_measurement: '°C'
      value_template: '{{ state_attr("sensor.tn_disk_temp", "ada1") }}'
    tn_ada2_temperature:
      unit_of_measurement: '°C'
      value_template: '{{ state_attr("sensor.tn_disk_temp", "ada2") }}'

# Storage percentage
- platform: rest
  name: TN pool
  resource: http://192.168.1.4/api/v2.0/pool/id/1
  headers:
    Authorization: !secret tn_api_key
    Content-Type: application/json
    User-Agent: Home Assistant
  value_template: '{{ value_json["status"] }}'
  json_attributes_path: '$.topology.data[0].stats'
  json_attributes:
    - allocated
    - size
  scan_interval: 1800
- platform: template
  sensors:
    tn_pool_pct_used:
      friendly_name: "% Used"
      value_template: ' {{ (state_attr("sensor.tn_pool", "allocated") / state_attr("sensor.tn_pool", "size") * 100) | round(1) }} '
      unit_of_measurement: "%"
14 Likes

The CPU temperature request and handling is quite cumbersome. I’m glad you figured it out and shared it!

I’ve tried looking at the online API documentation to find an easier to use endpoint for this information, but it loads soooo slowly and often crashes my browser.

I definitely can’t take credit for any of it. :smile: The cpu temperature part was posted by @troy.

hello reven! A true newbie here. First of all, Thanks you all very much for making things easier, and I apologize in advance for not being on your level. I’d like to know if you could help me get some information to make it work. The information I don’t understand is where do you get the api key for authorization? do you have to configure something in freenas? I tried to follow the steps but English is not my native language, so I got lost.