Integrating HP iLO2 entities into Home Assistant.
My lab environments are based on a hypervisor that doesn’t report the hardware status the way I want to. Here is where Home Assistant steps up to the plate. This platform is just insanely great at gathering information from a vast amount of (re)sources and enabling me to monitor, in a sense, the old-but-beefy, iLO2-equipped HP ML350-G6 servers.
The use case for my servers is running a lab environment for educational purposes. Giving easy insight into the statistics helps to keep the usage down to the necessary level only.
I know that the wingspan of the HP_iLO platform, open-sourced on Github, is not only restricted to iLO2. It can work with many more HP iLO versions. However, for this post, the focus is the HP iLO2 only.
The result of this configuration reflects the following, however, as always with Home Assistant, your mileage may vary. At least you learn from it!
Important note regarding CPU sensors
While observing the Temp 2
(CPU 1
) and Temp 3
(CPU 2
) I noticed that they stick at 40 degrees celsius at all times, even under very high environmental temperatures while all four fans running at 100% speed.
This was measured over different servers and scenarios. For this reason. I monitor the Temp 19: CPU Zone
and Temp 21: Storage Zone
to give meaningful information to the dashboard.
What to use?
For maximum functionality, I went for the Home Assistant OS (or Supervised), see; Home Assistant installation methods.
Benefits:
- Supervisor
- Studio Code Server add-on, web-enabled editor with code linting.
How to configure iLO integration
Adding the HP_iLO-integration to your Home Assistent is easy peasy.
Although there is, up to now, no GUI way of adding this YAML-based integration the configuration can be done by editing the /config/configuration.yaml
file.
I use the Studio Code Server add-on for the ease of altering the Home Assistant configuration files.
Please note that when using the latest iLO firmware you have to pay extra performance points, see my blog post; HP iLO2 extremely slow over HTTPS
Create specific accounts for the iLO2 system
For the ease of configuration and not handing out the full access credentials to Home Assistant I opted to create separate accounts on the iLO interface for the handling of the HP_iLO requests.
The user management (https://server01-ilo2.lab.corp/dusrpref.htm) on the iLO2 enables you, while logged in using the administrator role, to add/alter accounts.
Secrets configuration
There iLO2 specifics and credentials you stash in the /config/secrets.yaml
as there are referenced to in the main configuration file.
hpILOIP01: server01-ilo2.lab.corp
hpILOUsername: readonly
hpILOPassword: jvBqefEcwfm5PeqGkATjh6YJ
Checking the sensors
The integration is based on a YAML file. The colon-centered syntax of this so-called “human-friendly data serialization language” is very strict. Luckily the Visual Studio Code has a YAML code linting feature to help you out by highlighting syntax errors.
The hp_ilo integration details can be defined in the /config/configuration.yaml
.
Please note:
- The
scan_interval
has been set to 300 seconds to give the iLO2 time to respond for all monitored variables. The default value is set to 30 seconds according to the scan_interval documentation. - While checking the iLO I discovered that polling the root level of certain sensor_types resulted in a
State max length is 255 characters.
error. A little bit of digging got me to the issue described here on Github. Therefore I decided to document the iLO2 requirements in this blog post.
sensor:
- platform: hp_ilo
host: !secret hpILOIP01
username: !secret hpILOUsername
password: !secret hpILOPassword
scan_interval: 120
monitored_variables:
Below the monitored_variables
you can append each section to your config file.
System Status - Summary
The Summary on the System Status pages shows:
https://server01-ilo2.lab.corp/dqstat.htm
Requesting data | Response data |
---|---|
server_power_status | ON |
server_uid_status | OFF |
The power and UID only reports ON
, OFF
and for the UID the BLINKING
state is present.
- name: SERVER01_power_status
sensor_type: server_power_status
- name: SERVER01_uid_status
sensor_type: server_uid_status
Server Power Readings
Requesting data | Response data |
---|---|
sensor_type: server_power_readings unit_of_measurement: “Watts” server_power_readings value_template: “{{ ilo_data}}” |
{‘present_power_reading’: (186, ‘Watts’), ‘average_power_reading’: (186, ‘Watts’), ‘maximum_power_reading’: (281, ‘Watts’), ‘minimum_power_reading’: (185, ‘Watts’)} |
Interestingly you see that the reading is combined as in the value and the unit-size.
- name: SERVER01_power_readings
sensor_type: server_power_readings
unit_of_measurement: "Watts"
value_template: "{{ ilo_data.present_power_reading[0]}}"
Server Health - System Information - Summary
https://server01-ilo2.lab.corp/dhealth.htm
Requesting data | Response data |
---|---|
sensor_type: server_health value_template: “{{ ilo_data.health_at_a_glance }}” |
{‘fans’: {‘status’: ‘Ok’, ‘redundancy’: ‘Fully Redundant’}, ‘temperature’: {‘status’: ‘Ok’}, ‘vrm’: {‘status’: ‘Ok’}, ‘power_supplies’: {‘status’: ‘Ok’, ‘redundancy’: ‘Not Redundant’}, ‘drive’: {‘status’: ‘Ok’}} |
From this you can define the following sensors.
- name: SERVER01_haag_fans_status
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['fans']['status'] }}"
- name: SERVER01_haag_fans_redundancy
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['fans']['redundancy'] }}"
- name: SERVER01_haag_temperature_status
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['temperature']['status'] }}"
- name: SERVER01_haag_vrm_status
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['vrm']['status'] }}"
- name: SERVER01_haag_powersupplies_status
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['powersupplies']['status'] }}"
- name: SERVER01_haag_powersupplies_redundancy
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['powersupplies']['redundancy'] }}"
- name: SERVER01_haag_drive_status
sensor_type: server_health
value_template: "{{ ilo_data.health_at_a_glance['drive']['status'] }}"
In this case the general health of the fans will be shown as Ok
, the fans redundancy will be shown as Fully Redudant
and the powersupply are reported as Not Redundant
.
System Information - Fans
https://server01-ilo2.lab.corp/dhealthf.htm
Using the Home Assistent developer tools;
Requesting data | Response data |
---|---|
sensor_type: server_health unit_of_measurement: “%” value_template: ‘{{ ilo_data.fans[“Fan 1”] }}’ |
{‘label’: ‘Fan 1’, ‘zone’: ‘System’, ‘status’: ‘Ok’, ‘speed’: (26, ‘Percentage’)} |
sensor_type: server_health unit_of_measurement: “%” value_template: ‘{{ ilo_data.fans[“Fan 2”] }}’ |
{‘label’: ‘Fan 2’, ‘zone’: ‘System’, ‘status’: ‘Ok’, ‘speed’: (21, ‘Percentage’)} |
sensor_type: server_health unit_of_measurement: “%” value_template: ‘{{ ilo_data.fans[“Fan 3”] }}’ |
{‘label’: ‘Fan 3’, ‘zone’: ‘System’, ‘status’: ‘Ok’, ‘speed’: (31, ‘Percentage’)} |
sensor_type: server_health unit_of_measurement: “%” value_template: ‘{{ ilo_data.fans[“Fan 4”] }}’ |
{‘label’: ‘Fan 4’, ‘zone’: ‘System’, ‘status’: ‘Ok’, ‘speed’: (30, ‘Percentage’)} |
From this I distilled the following sensor configuration;
- name: SERVER01_health_fan_1_speed
sensor_type: server_health
unit_of_measurement: "%"
value_template: '{{ ilo_data.fans["Fan 1"].speed[0] }}'
- name: SERVER01_health_fan_2_speed
sensor_type: server_health
unit_of_measurement: "%"
value_template: '{{ ilo_data.fans["Fan 2"].speed[0] }}'
- name: SERVER01_health_fan_3_speed
sensor_type: server_health
unit_of_measurement: "%"
value_template: '{{ ilo_data.fans["Fan 3"].speed[0] }}'
- name: SERVER01_health_fan_4_speed
sensor_type: server_health
unit_of_measurement: "%"
value_template: '{{ ilo_data.fans["Fan 4"].speed[0] }}'
System Information - Temperatures
From the temperature overview in ILO2, in my case https://server01-ilo2.lab.corp/dhealtht.htm
, I took the Health Temperature info and noted the number of temperature sensors. Those sensors I mapped to the values I wanted to retrieve using Home Assistant.
Please note that the sensor `caution’ and ‘critical’ levels vary per sensor.
https://server01-ilo2.lab.corp/dhealtht.htm
Sensor number | Description | Requesting data | Response data |
---|---|---|---|
01 | Ambient Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 1”].currentreading[0] }}’ |
{‘label’: ‘Temp 1’, ‘location’: ‘Ambient’, ‘status’: ‘Ok’, ‘currentreading’: (28, ‘Celsius’), ‘caution’: (42, ‘Celsius’), ‘critical’: (46, ‘Celsius’)} |
02 | CPU 1 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 2”].currentreading[0] }}’ |
{‘label’: ‘Temp 2’, ‘location’: ‘CPU 1’, ‘status’: ‘Ok’, ‘currentreading’: (40, ‘Celsius’), ‘caution’: (82, ‘Celsius’), ‘critical’: (83, ‘Celsius’)} |
03 | CPU 2 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 3”].currentreading[0] }}’ |
{‘label’: ‘Temp 3’, ‘location’: ‘CPU 2’, ‘status’: ‘Ok’, ‘currentreading’: (40, ‘Celsius’), ‘caution’: (82, ‘Celsius’), ‘critical’: (83, ‘Celsius’)} |
04 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 4”].currentreading[0] }}’ |
{‘label’: ‘Temp 4’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (42, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
05 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 5”].currentreading[0] }}’ |
{‘label’: ‘Temp 5’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (36, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
06 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 6”].currentreading[0] }}’ |
{‘label’: ‘Temp 6’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (36, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
07 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 7”].currentreading[0] }}’ |
{‘label’: ‘Temp 7’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (36, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
08 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 8”].currentreading[0] }}’ |
{‘label’: ‘Temp 8’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (39, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
09 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 9”].currentreading[0] }}’ |
{‘label’: ‘Temp 9’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (40, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
10 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 10”].currentreading[0] }}’ |
{‘label’: ‘Temp 10’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (43, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
11 | Memory Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 11”].currentreading[0] }}’ |
{‘label’: ‘Temp 11’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (47, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
12 | I/O Board 7 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 12”].currentreading[0] }}’ |
{‘label’: ‘Temp 12’, ‘location’: ‘I/O Board 7’, ‘status’: ‘Ok’, ‘currentreading’: (47, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
13 | I/O Board 6 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 13”].currentreading[0] }}’ |
{‘label’: ‘Temp 13’, ‘location’: ‘I/O Board 6’, ‘status’: ‘Ok’, ‘currentreading’: (46, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
14 | I/O Board 5 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 14”].currentreading[0] }}’ |
{‘label’: ‘Temp 14’, ‘location’: ‘I/O Board 5’, ‘status’: ‘Ok’, ‘currentreading’: (43, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
15 | I/O Board 4 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 15”].currentreading[0] }}’ |
{‘label’: ‘Temp 15’, ‘location’: ‘I/O Board 4’, ‘status’: ‘Ok’, ‘currentreading’: (41, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
16 | I/O Board 3 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 16”].currentreading[0] }}’ |
{‘label’: ‘Temp 16’, ‘location’: ‘I/O Board 3’, ‘status’: ‘Ok’, ‘currentreading’: (39, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
17 | I/O Board 2 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 17”].currentreading[0] }}’ |
{‘label’: ‘Temp 17’, ‘location’: ‘I/O Board 2’, ‘status’: ‘Ok’, ‘currentreading’: (37, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
18 | I/O Board 1 | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 18”].currentreading[0] }}’ |
{‘label’: ‘Temp 18’, ‘location’: ‘I/O Board 1’, ‘status’: ‘Ok’, ‘currentreading’: (37, ‘Celsius’), ‘caution’: (68, ‘Celsius’), ‘critical’: (73, ‘Celsius’)} |
19 | CPU Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 19”].currentreading[0] }}’ |
{‘label’: ‘Temp 19’, ‘location’: ‘CPU’, ‘status’: ‘Ok’, ‘currentreading’: (35, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
20 | Memory Board | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 20”].currentreading[0] }}’ |
{‘label’: ‘Temp 20’, ‘location’: ‘Memory’, ‘status’: ‘Ok’, ‘currentreading’: (38, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
21 | SCSI BackPlane | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 21”].currentreading[0] }}’ |
{‘label’: ‘Temp 21’, ‘location’: ‘Storage’, ‘status’: ‘Ok’, ‘currentreading’: (35, ‘Celsius’), ‘caution’: (60, ‘Celsius’), ‘critical’: (65, ‘Celsius’)} |
22 | System Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 22”].currentreading[0] }}’ |
{‘label’: ‘Temp 22’, ‘location’: ‘System’, ‘status’: ‘Ok’, ‘currentreading’: (69, ‘Celsius’), ‘caution’: (110, ‘Celsius’), ‘critical’: (115, ‘Celsius’)} |
23 | System Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 23”].currentreading[0] }}’ |
{‘label’: ‘Temp 23’, ‘location’: ‘System’, ‘status’: ‘Ok’, ‘currentreading’: (46, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
24 | System Zone | sensor_type: server_health unit_of_measurement: “°C” value_template: ‘{{ ilo_data.temperature[“Temp 24”].currentreading[0] }}’ |
{‘label’: ‘Temp 24’, ‘location’: ‘System’, ‘status’: ‘Ok’, ‘currentreading’: (49, ‘Celsius’), ‘caution’: (87, ‘Celsius’), ‘critical’: (92, ‘Celsius’)} |
Again, I extracted the values to get some sensible data into the HASS dashboard. I didn’t take every measurement in account as this dramatically increases the time needed to harvest the information.
- name: SERVER01_temp_ambient
sensor_type: server_health
unit_of_measurement: "°C"
value_template: '{{ ilo_data.temperature["Temp 1"].currentreading[0] }}'
- name: SERVER01_temp_cpu_zone
sensor_type: server_health
unit_of_measurement: "°C"
value_template: '{{ ilo_data.temperature["Temp 19"].currentreading[0] }}'
- name: SERVER01_temp_storage_zone
sensor_type: server_health
unit_of_measurement: "°C"
value_template: '{{ ilo_data.temperature["Temp 21"].currentreading[0] }}'
System Information - Power
https://server01-ilo2.lab.corp/dhealthv.htm
System Information - Processors
https://server01-ilo2.lab.corp/dsysproc.htm
System Information - Memory
https://server01-ilo2.lab.corp/dsysmem.htm
System Information - NIC
https://server01-ilo2.lab.corp/dhealthp.htm
System Information - Drives
https://server01-ilo2.lab.corp/dhealthd.htm
Lovelace card configuration
Showing your harvested data into a card on the overview is the next step.
Firstly navigate in the browser to the overview dashboard.
Create a card and navigate to the ‘show code editor`. From here you can overwrite the content with the code mentioned below.
This conditional card will only be shown when the iLO reports itself when the power status is ON
.
type: conditional
conditions:
- entity: sensor.hp_ilo_server01_power_status
state: 'ON'
card:
title: iLO2 Server01
state_color: true
header:
type: graph
entity: sensor.hp_ilo_server01_temp_ambient
detail: 2
type: entities
entities:
- entity: sensor.hp_ilo_server01_power_status
name: 'Power status changed:'
icon: mdi:power
secondary_info: last-changed
- entity: sensor.hp_ilo_server01_uid_status
name: 'UID LED changed:'
icon: mdi:led-on
secondary_info: last-changed
- entity: sensor.hp_ilo_server01_temp_ambient
name: 'Ambient Temp updated:'
secondary_info: last-updated
- entity: sensor.hp_ilo_server01_temp_cpu_zone
name: 'CPU Zone Temp updated:'
secondary_info: last-updated
- entity: sensor.hp_ilo_server01_temp_storage_zone
name: 'Storage Zone Temp updated:'
secondary_info: last-updated
- entity: sensor.hp_ilo_server01_power_readings
secondary_info: last-updated
name: 'Power consumption updated:'
icon: mdi:power-plug
- entity: sensor.hp_ilo_server01_health_fan_1_speed
secondary_info: last-updated
name: 'Fan 1 updated:'
icon: mdi:fan
- entity: sensor.hp_ilo_server01_health_fan_2_speed
secondary_info: last-updated
name: 'Fan 2 updated:'
icon: mdi:fan
- entity: sensor.hp_ilo_server01_health_fan_3_speed
secondary_info: last-updated
name: 'Fan 3 updated:'
icon: mdi:fan
- entity: sensor.hp_ilo_server01_health_fan_4_speed
secondary_info: last-updated
name: 'Fan 4 updated:'
icon: mdi:fan
Homework / Reference information
HP iLO2 Scripting and Command Line Guide