Advanced SNMP monitoring, part two: FreeNAS

Part I (Asuswrt): Advanced SNMP monitoring, part one: Asuswrt routers (Merlin build)
Part III (pfSense): TBC

Note 1: in the current firmware versions only extend directive works (exec directive is no longer supported) and this creates a different structure for OID. Use snmpwalk to get the values for all of the OIDs below if Home Assistant doesn’t get the values for the sensors, for example: snmpwalk -c public -v2c 192.168.0.36 1.3.6.1.2.1.25.1.8

which would result in 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1 as the desired value.

iso.3.6.1.2.1.25.1.8.1.0 = INTEGER: 1
iso.3.6.1.2.1.25.1.8.2.1.2.7.47.98.105.110.47.115.104 = STRING: "/mnt/Data/files/SNMP/snmp-cpu-0-temp.sh"
iso.3.6.1.2.1.25.1.8.2.1.3.7.47.98.105.110.47.115.104 = ""
iso.3.6.1.2.1.25.1.8.2.1.4.7.47.98.105.110.47.115.104 = ""
iso.3.6.1.2.1.25.1.8.2.1.5.7.47.98.105.110.47.115.104 = INTEGER: 5
iso.3.6.1.2.1.25.1.8.2.1.6.7.47.98.105.110.47.115.104 = INTEGER: 1
iso.3.6.1.2.1.25.1.8.2.1.7.7.47.98.105.110.47.115.104 = INTEGER: 1
iso.3.6.1.2.1.25.1.8.2.1.20.7.47.98.105.110.47.115.104 = INTEGER: 4
iso.3.6.1.2.1.25.1.8.2.1.21.7.47.98.105.110.47.115.104 = INTEGER: 1
iso.3.6.1.2.1.25.1.8.3.1.1.7.47.98.105.110.47.115.104 = STRING: "54.0"
iso.3.6.1.2.1.25.1.8.3.1.2.7.47.98.105.110.47.115.104 = STRING: "54.0"
iso.3.6.1.2.1.25.1.8.3.1.3.7.47.98.105.110.47.115.104 = INTEGER: 1
iso.3.6.1.2.1.25.1.8.3.1.4.7.47.98.105.110.47.115.104 = INTEGER: 0
iso.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1 = STRING: "54.0"

A. FreeNAS setup (IP of the FreeNAS machine is 192.168.0.36)

I. Find a suitable place for storing the SNMP scripts (I’ve used /mnt/Data/files/SNMP/) and create script files:

root@freenas[~]# nano /mnt/Data/files/SNMP/name_of_the_script.sh

  1. snmp-cpu-0-temp
#!/bin/sh

sysctl -a | egrep -E "cpu\.0+\.temp" | awk '{print $2}' | cut -c 1,2,3,4
  1. snmp-cpu-idle
#!/bin/sh

vmstat 2 2 | awk 'FNR==4{print $19}'
  1. snmp-diskx-temp (copy for each additional drive)
#!/bin/sh

/usr/local/sbin/smartctl -A /dev/ada0 | grep -i Temperature_Celsius | awk '{print $10}'
  1. snmp-space-free
#!/bin/sh

zfs list | head -2| awk '/Data/ {print $1}' | rev | cut -c2,3,4,5 | rev

II. Enable SNMP in FreeNAS -> Services - > SNMP
III. In Action for SNMP service include the following auxiliary parameters:

extend .1.3.6.1.2.1.25.1.8 /bin/sh /mnt/Data/files/SNMP/snmp-cpu-0-temp.sh
extend .1.3.6.1.2.1.25.1.10 /bin/sh /mnt/Data/files/SNMP/snmp-cpu-idle.sh
extend .1.3.6.1.2.1.25.1.11 /bin/sh /mnt/Data/files/SNMP/snmp-disk0-temp.sh
extend .1.3.6.1.2.1.25.1.12 /bin/sh /mnt/Data/files/SNMP/snmp-disk1-temp.sh
extend .1.3.6.1.2.1.25.1.13 /bin/sh /mnt/Data/files/SNMP/snmp-disk2-temp.sh
extend .1.3.6.1.2.1.25.1.14 /bin/sh /mnt/Data/files/SNMP/snmp-disk3-temp.sh
extend .1.3.6.1.2.1.25.1.15 /bin/sh /mnt/Data/files/SNMP/snmp-space-free.sh

B. Home Assistant
Make sure you add the packages in configuration.yaml (if starting recently with Home Assistant you would not have the homeassistant: line in configuration.yaml)

homeassistant:
  packages: !include_dir_named packages
#Package SNMP monitoring for FreeNAS
homeassistant:
  customize:
#Some cosmetics (not really necessary)
    switch.freenaswol:
      friendly_name: FreeNAS WOL
      icon: mdi:desktop-classic
      assumed_state: true
    sensor.freenas_cpu_temperature:
      friendly_name: CPU Temp
    sensor.freenas_cpu_used:
      friendly_name: CPU Used
      icon: mdi:cpu-64-bit
    sensor.freenas_space_free:
      friendly_name: Space Free
      icon: mdi:harddisk
    sensor.freenas_disk0_temperature:
      friendly_name: Disk0 Temp
    sensor.freenas_disk1_temperature:
      friendly_name: Disk1 Temp
    sensor.freenas_disk2_temperature:
      friendly_name: Disk2 Temp
    sensor.freenas_disk3_temperature:
      friendly_name: Disk3 Temp

switch:
  - platform: wake_on_lan
    mac_address: "11-11-11-11-11-11"
    name: freenaswol
    host: 192.168.0.36
    broadcast_address: 255.255.255.255
    turn_off:
      service: shell_command.turn_off_freenas

shell_command:
  - turn_off_freenas: 'bash ssh -tt [email protected] /sbin/shutdown -p now'

#Note: Login without password is covered in https://community.home-assistant.io/t/internet-kill-switch-for-both-wireless-wired-devices/135785
# At least a successful connection from Home Assistant to FreeNAS machine is needed.
    
sensor:
#Standard 
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.4.1.2021.10.1.3.1
    name: freenas_1min_load
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: ' '
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.4.1.2021.10.1.3.2
    name: freenas_5min_load
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: ' '
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.4.1.2021.10.1.3.3
    name: freenas_15min_load
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: ' '
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.1.0
    name: freenas_uptime
    accept_errors: true
    default_value: 0
    scan_interval: 35
    value_template: >-
      {% set time = (value | int) | int %}
      {% set minutes = ((time % 360000) / 6000) | int%}
      {% set hours = ((time % 8640000) / 360000) | int %}
      {% set days = (time / 8640000) | int %}
        {%- if time < 60 -%}
          Less then 1 min
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }}d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ hours }}hr
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }}min
          {%- endif -%}
        {%- endif -%}
  
#Non-sttandard
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_cpu_temperature
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: '°C'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.10.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_cpu_used
    accept_errors: true
    default_value: 0
    value_template: '{{100-(value | float  | round (2)) }}'
    unit_of_measurement: '%'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.11.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_disk0_temperature
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: '°C'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.12.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_disk1_temperature
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: '°C'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.13.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_disk2_temperature
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: '°C'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.14.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_disk3_temperature
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: '°C'
    scan_interval: 35
  - platform: snmp
    host: 192.168.0.36
    baseoid: 1.3.6.1.2.1.25.1.15.4.1.2.7.47.98.105.110.47.115.104.1
    name: freenas_space_free
    accept_errors: true
    default_value: 0
    value_template: '{{value | float  | round (2) }}'
    unit_of_measurement: 'GB'
    scan_interval: 35

Content for the Lovelace card; this includes modifications such as weblink, switch behaves differently when machine is on (in order to prevent accidentally turning it off):

cards:
  - card:
      content: >
        [Web access FreeNAS](http://192.168.0.36) Uptime:
        {{states.sensor.freenas_uptime.state}}
      type: markdown
    conditions:
      - entity: switch.freenaswol
        state: 'on'
    type: conditional
  - card:
      entities:
        - entity: switch.freenaswol
      type: entities
    conditions:
      - entity: switch.freenaswol
        state: 'off'
    type: conditional
  - card:
      entities:
        - entity: sensor.freenas_1min_load
        - entity: sensor.freenas_5min_load
        - entity: sensor.freenas_15min_load
        - entity: sensor.freenas_cpu_temperature
        - entity: switch.freenaswol
        - entity: sensor.freenas_cpu_used
        - entity: sensor.freenas_space_free
        - entity: sensor.freenas_disk0_temperature
        - entity: sensor.freenas_disk1_temperature
        - entity: sensor.freenas_disk2_temperature
        - entity: sensor.freenas_disk3_temperature
      type: glance
    conditions:
      - entity: switch.freenaswol
        state: 'on'
    type: conditional
title: FreeNAS Machine
type: 'custom:vertical-stack-in-card'

This is the card when machine is off:
FreeNASoff

And when on:
FreeNASon

5 Likes

Any ETA on the pfSense tutorial? :relaxed:

1 Like

Will try to do it :slight_smile:

Despite the common FreeBSD heritage, the default SNMP service in pfSense doesn’t allow for custom commands results to be passed (but net-snmp package works for this and can be expanded with the results of any command).

Was hopping that the RESTCONF api would be deployed after all; however, as RESTCONF api won’t be included in 2.5.0, still have to deal with other solutions.

2 Likes

Amazing work!!!
thank you for sharing.
could you please share where you got the mib references for freenas? - i could not find through DR google or freenas website and manual scripted content seems to be broken in my case on freenas 11.3

Hi @aviv128,

I’ve mainly used snmpwalk to test OIDs I got from googling different sources (both FreeBSD and Linux). After I found that not all the resources I wanted are available in FreeNAS, then I started looking into adding custom scripts values.

I don’t understand. Can you elaborate?

Hi @Petrica

I assume i did something wrong but could not figure it out even after a lot of searching the web.
i am adding screenshots bellow of my scenario hoping this will clarify:

For a reason i could not figure out the custom scripts you made are not working for me

Hello,

Could you share the result of the following command (run it on FreeNAS):

cat /mnt/Apartment9/Automation/SNMP/snmp-cpu-0.sh

Is it an error?

Or the following (this would be the result case the scripts are correctly pointed to)?

#!/bin/sh
sysctl -a | egrep -E “cpu.0+.temp” | awk ‘{print $2}’ | cut -c 1,2,3,4

I know that the best thing would have been uploading a step-by-step video (but since I’m not an English native speaker, this might have caused even more problems; actually I’m a native speaker of the sole Romance language in the Eastern Europe, which is obviously not half as bad as speaking French, Elvish or Klingon :smile: ) but I will update the page to include printscreens.

1 Like

Thanks @Petrica for beeing so helpfull

Your guide is amazing just not dummy proof - case and point = myself, hopefully others will encounter similar issue and this might help them because as any FreeNAS user know - it have a lot of value (and look great :stuck_out_tongue_winking_eye:)
also dos2unix powershell one liner did not fix snmp-space-free.sh issue nor adding bash before the shell.

Hello,

  1. Even if the script exist on the respective location (which I thought was the issue in the first place), you still need to use “sh” before the name in order to run it:

sh /mnt/Apartment9/Automation/SNMP/snmp-space-free.sh

  1. You need to update the script for your particular setup as the storage pool name is different (in my case it was called “Data”, however you have “Apartment9”
1 Like

stupid me - missed that one, still have some issue but that is FreeBSD syntax related, cut don’t show char above the 10th, will figure it out later. thank you!!!

root@apt9:~ # zfs list | head -2
NAME                                                                   USED  AVAIL  REFER  MOUNTPOINT
Apartment9                                                            1.56T  2.24T  1.21T  /mnt/Apartment9
root@apt9:~ # zfs list | head -2 | awk '/Apartment9/ {print $1}' | rev | cut -c1-30 | rev
Apartment9

any chance you know why disk temp not presented in home assistant -just stay 0? script as shown above seems to work but does not presented in HA - developer tools entity state shows 0.0/
home assistant sensor config is same as above except the IP.

use $2 instead:
zfs list | head -2 | awk '/Apartment9/ {print $2}' | rev | cut -c1-30 | rev

You need to have SMART enabled for the HDD. What does the command /usr/local/sbin/smartctl -A /dev/ada0 show (on FreeNAS)? You’re looking for the value at the intersection between line Temperature_Celsius and the column no. 10 ('{print $10}')

On the same principle you can add some other important values (ie Offline_Uncorrectable)

root@fnmediaserver[/mnt/Data/files/SNMP]# /usr/local/sbin/smartctl -A /dev/ada0
smartctl 7.0 2018-12-30 r4883 [FreeBSD 11.3-RELEASE-p7 amd64] (local build)
Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 10
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   074   064   006    Pre-fail  Always       -       24814952
  3 Spin_Up_Time            0x0003   096   096   000    Pre-fail  Always       -       0
  4 Start_Stop_Count        0x0032   100   100   020    Old_age   Always       -       11
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000f   087   060   045    Pre-fail  Always       -       509576332
  9 Power_On_Hours          0x0032   097   097   000    Old_age   Always       -       3177 (94 62 0)
 10 Spin_Retry_Count        0x0013   100   100   097    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   020    Old_age   Always       -       11
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error        0x0032   100   100   099    Old_age   Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
188 Command_Timeout         0x0032   100   099   000    Old_age   Always       -       12885164036
189 High_Fly_Writes         0x003a   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0022   060   058   040    Old_age   Always       -       40 (Min/Max 37/42)
191 G-Sense_Error_Rate      0x0032   100   100   000    Old_age   Always       -       0
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       115
193 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       138
194 Temperature_Celsius     0x0022   040   042   000    Old_age   Always       -       40 (0 24 0 0 0)
195 Hardware_ECC_Recovered  0x001a   074   064   000    Old_age   Always       -       24814952
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
240 Head_Flying_Hours       0x0000   100   253   000    Old_age   Offline      -       3177 (248 36 0)
241 Total_LBAs_Written      0x0000   100   253   000    Old_age   Offline      -       18173217792
242 Total_LBAs_Read         0x0000   100   253   000    Old_age   Offline      -       27889292335
1 Like

$2 indeed solve the script issue!!!
But actually all scripts works perfectly when ran from ssh on FreeNAS, but data is not updated in HA.

running from ssh in freenas:

root@apt9:~ # sh /mnt/Apartment9/Automation/SNMP/snmp-disk0.sh
: not foundent9/Automation/SNMP/snmp-disk0.sh:
48
root@apt9:~ # sh /mnt/Apartment9/Automation/SNMP/snmp-disk2.sh
: not foundent9/Automation/SNMP/snmp-disk2.sh:
40
root@apt9:~ # sh /mnt/Apartment9/Automation/SNMP/snmp-space-free.sh
1.51T
root@apt9:~ #

sensor config:

  #Non-sttandard
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_cpu_temperature'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: '°C'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.10.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_cpu_used'
  accept_errors: true
  default_value: 0
  value_template: '{{100-(value | float  | round (2)) }}'
  unit_of_measurement: '%'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.11.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_disk0_temperature'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: '°C'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.12.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_disk1_temperature'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: '°C'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.13.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_disk2_temperature'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: '°C'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.1.14.4.1.2.7.47.98.105.110.47.115.104.1
  name: 'freenas_disk3_temperature'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: '°C'
  scan_interval: 35
- platform: snmp
  host: 192.168.2.200
  baseoid: 1.3.6.1.2.1.25.15.2.1.2.7.47.98.105.110.47.115.104
  name: 'freenas_space_free'
  accept_errors: true
  default_value: 0
  value_template: '{{value | float  | round (2) }}'
  unit_of_measurement: 'GB'
  scan_interval: 35

What does the snmpwalk command result on the FreeNAS machine (first try with 127.0.0.1, then with 192.168.2.200)?

snmpwalk -c public -v2c 127.0.0.1 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1

If it works, then probably it is a parsing error in HA. Otherwise, the script results were not loaded by SNMP.

1 Like

Seems like it the HA option :cry: , so i guess there is nothing really to do there…

root@apt9:~ # snmpwalk -c public -v2c 127.0.0.1 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1
HOST-RESOURCES-MIB::hrSystem.8.4.1.2.7.47.98.105.110.47.115.104.1 = STRING: "41.0"
root@apt9:~ # snmpwalk -c public -v2c 192.168.2.200 1.3.6.1.2.1.25.1.8.4.1.2.7.47.98.105.110.47.115.104.1
HOST-RESOURCES-MIB::hrSystem.8.4.1.2.7.47.98.105.110.47.115.104.1 = STRING: "38.0"
root@apt9:~ #

still would like to thank you very much @Petrica !!! you are a really patience and amazing help

UPDATE, my free-space script result included the letter “T” which messed the info for HA.
once aligned the “cut” command to include numbers only everything works perfectly - thanks again @Petrica

You’re welcome!