Unraid System Monitor integration

For those running HA on Unraid would be nice to fetch system monitor data about CPU, HDDs etc.
Unraid display nice piece of data, so there is no need install Glances for example.

Im not using Unraid, but have you seen this? https://forums.unraid.net/topic/39339-plug-in-snmp/

it is not what I am looking for. Thanks anyway

What’s wrong with SNMP if I may ask, I’m monitoring various servers and other IT devices through SNMP, it definetly allows to monitor CPU, mem, HDD usage and thousands of other parameters of my servers.

I started trying to do this but haven’t had a lot of time. What I figured out is that if you’re running HA in your Unraid instance then you can mount usr/local/emhttp/state and pass it to HA (important to do as read-only), then you’ll need to parse the contents.
This is my EXTREMELY HACKY version of a custom component is available here in case someone wants to spend some time turning it into something decent.

"""Support for Unraid disk usage"""
from datetime import timedelta, datetime
import logging
import configparser


from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.helpers.entity import Entity

_LOGGER = logging.getLogger(__name__)

TIME_BETWEEN_UPDATES = timedelta(minutes=5)


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the sensor platform."""
    add_devices([UnraidDiskSensor()])


class UnraidDiskSensor(Entity):
    """Representation of a Sensor."""

    def __init__(self):
        """Initialize the sensor."""
        self._name = "Unraid Disk Sensor"
        self._attributes = {}
        self._state = None
        self.disk_details = {}

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._name

    @property
    def state(self):
        """Return the state of the sensor."""
        return self._state

    @property
    def icon(self):
        "Icon to use in frontend"
        return 'mdi:database'

    @property
    def device_state_attributes(self):
        """Return attributes for the sensor."""
        self._attributes = self.testFunc()
        return self._attributes


    @property
    def unit_of_measurement(self):
        """Return the unit of measurement."""
        return "%"





    def update(self):
        """Fetch new state data for the sensor.

        This is the only method that should fetch new data for Home Assistant.
        """
        ###!!!!! Use the total utilization!!!!!
        self._attributes = self.testFunc()
        self._state = self._attributes['total_utilization']



    def testFunc(self):
        config = configparser.ConfigParser()
        config.read('/unraid_metrics/disks.ini')

        sections = config.sections()

        disks = {}
        total_utilization = 0
        num_data_disks = 0
        for d in sections:
            disk_details = {}

            if config[d]['status'] not in ['"DISK_NP"', '"DISK_NP_DSBL"']:
                if config[d]['type'] in ['"Data"', '"Cache"']:
                    fsSize = int(config[d]['fsSize'][1:-1])
                    fsFree = int(config[d]['fsFree'][1:-1])
                    utilizationPct = round((1 - (fsFree / fsSize)) * 100, 2)
                else:
                    utilizationPct = 0

                key = d.replace('"', '')
                disk_details['status'] = config[d]['status'].replace('"', '')
                disk_details['type'] = config[d]['type'].replace('"', '')
                disk_details['name'] = config[d]['name'].replace('"', '')
                disk_details['device'] = config[d]['device'].replace('"', '')
                disk_details['temp'] = config[d]['temp'][1:-1]
                disk_details['utilization'] = utilizationPct
                disks[key] = disk_details

                if config[d]['type'] == '"Data"':
                    total_utilization = total_utilization + utilizationPct
                    num_data_disks = num_data_disks+1



        ##get overall usage
        disks['total_utilization'] = round(total_utilization/num_data_disks,2)
        disks['last_updated'] = str(datetime.now())

This seems great, However I seem to get this error

Update for sensor.unraid_disk_sensor fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 281, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 461, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/unraid/sensor.py", line 68, in update
    self._state = self._attributes['total_utilization'][0]
TypeError: 'NoneType' object is not subscriptable

Perhaps you have an updated script?

Still using the same script with no issues.
From your error I think you might have an extra [0] after [‘total_utilization’]… can you remove the [0] and let me know if that did the trick? If not ill try to have a look

sorry, ignore the [0] i was trying stuff to try and make it work, even without that it still doesn’t seem to work. any ideas?

what version of HA you on?

(not sure what happened to my other posts, HA forum and my browser went a bit weird)

Can you make sure you are you mounting unraid’s folder: usr/local/emhttp/state (which is where all the infor is stored) as read only into a folder in the hass container named unraid_metrics

Yeah i am, i can access it from the homeassistant docker via exec aswell, permissions potentially an issue if homeassistant it self runs under a different user to the docker exec?

So i decided to go a more plug and play route, here is a unraid plugint that converts the ini files to json for easy reading from HA with a rest sensor Unraid JSON API