Skip to content

Commit

Permalink
Fix multiple devices not working properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Breina committed Apr 29, 2024
1 parent 09b8fce commit 3c90414
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 29 deletions.
29 changes: 20 additions & 9 deletions custom_components/idrac_power/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,30 @@
from homeassistant.core import HomeAssistant

from .const import DOMAIN, DATA_IDRAC_REST_CLIENT, HOST, USERNAME, PASSWORD, CONF_INTERVAL, CONF_INTERVAL_DEFAULT
from .idrac_rest import IdracRest
from .idrac_rest import IdracMock, IdracRest


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up the iDrac connection from a config entry."""
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
DATA_IDRAC_REST_CLIENT: IdracRest(
entry.data[HOST],
entry.data[USERNAME],
entry.data[PASSWORD],
entry.data.get(CONF_INTERVAL, CONF_INTERVAL_DEFAULT)
)
}

if entry.data[HOST] == 'MOCK':
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
DATA_IDRAC_REST_CLIENT: IdracMock(
entry.data[HOST],
entry.data[USERNAME],
entry.data[PASSWORD],
entry.data.get(CONF_INTERVAL, CONF_INTERVAL_DEFAULT)
)
}
else:
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
DATA_IDRAC_REST_CLIENT: IdracRest(
entry.data[HOST],
entry.data[USERNAME],
entry.data[PASSWORD],
entry.data.get(CONF_INTERVAL, CONF_INTERVAL_DEFAULT)
)
}

hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
Expand Down
2 changes: 1 addition & 1 deletion custom_components/idrac_power/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
serial = info[JSON_SERIAL_NUMBER]

device_info = DeviceInfo(
identifiers={('domain', DOMAIN), ('model', model), ('serial', serial)},
identifiers={('serial', serial)},
name=name,
manufacturer=manufacturer,
model=model,
Expand Down
2 changes: 1 addition & 1 deletion custom_components/idrac_power/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
serial = info[JSON_SERIAL_NUMBER]

device_info = DeviceInfo(
identifiers={('domain', DOMAIN), ('model', model), ('serial', serial)},
identifiers={('serial', serial)},
name=name,
manufacturer=manufacturer,
model=model,
Expand Down
22 changes: 15 additions & 7 deletions custom_components/idrac_power/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .const import (
DOMAIN, JSON_MODEL, CONF_INTERVAL, CONF_INTERVAL_DEFAULT,
)
from .idrac_rest import IdracRest, CannotConnect, InvalidAuth, RedfishConfig
from .idrac_rest import IdracRest, CannotConnect, InvalidAuth, RedfishConfig, IdracMock

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -65,12 +65,20 @@ async def async_step_user(
)

async def validate_input(self, data: dict[str, Any]) -> dict[str, Any]:
rest_client = IdracRest(
host=data[CONF_HOST],
username=data[CONF_USERNAME],
password=data[CONF_PASSWORD],
interval=data[CONF_INTERVAL],
)
if data[CONF_HOST] == 'MOCK':
rest_client = IdracMock(
host=data[CONF_HOST],
username=data[CONF_USERNAME],
password=data[CONF_PASSWORD],
interval=data[CONF_INTERVAL],
)
else:
rest_client = IdracRest(
host=data[CONF_HOST],
username=data[CONF_USERNAME],
password=data[CONF_PASSWORD],
interval=data[CONF_INTERVAL],
)

device_info = await hass.async_add_executor_job(self.hass, target=rest_client.get_device_info)
model_name = device_info[JSON_MODEL]
Expand Down
66 changes: 66 additions & 0 deletions custom_components/idrac_power/idrac_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,69 @@ class InvalidAuth(HomeAssistantError):

class RedfishConfig(HomeAssistantError):
"""Error to indicate that Redfish was not properly configured"""


class IdracMock(IdracRest):
def __init__(self, host, username, password, interval):
super().__init__(host, username, password, interval)

def get_device_info(self):
return {
JSON_NAME: "Mock Device",
JSON_MANUFACTURER: "Mock Manufacturer",
JSON_MODEL: "Mock Model",
JSON_SERIAL_NUMBER: "Mock Serial"
}

def get_firmware_version(self):
return "1.0.0"

def power_on(self):
return "ON"

def update_thermals(self) -> dict:
new_thermals = {
'Fans': [
{
'FanName': "First Mock Fan",
'Reading': 1
},
{
'FanName': "Second Mock Fan",
'Reading': 2
}
],
'Temperatures': [
{
'Name': "Mock Temperature",
'ReadingCelsius': 10
}
]
}

if new_thermals != self.thermal_values:
self.thermal_values = new_thermals
for callback in self.callback_thermals:
callback(self.thermal_values)
return self.thermal_values

def update_status(self):
new_status = True

if new_status != self.status:
self.status = new_status
for callback in self.callback_status:
callback(self.status)

def update_power_usage(self):
power_values = {
JSON_POWER_CONSUMED_WATTS: 100
}
try:
new_power_usage = power_values[JSON_POWER_CONSUMED_WATTS]
if new_power_usage != self.power_usage:
self.power_usage = new_power_usage
for callback in self.callback_power_usage:
callback(self.power_usage)
except:
pass
22 changes: 11 additions & 11 deletions custom_components/idrac_power/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
"""Add iDrac power sensor entry"""
rest_client = hass.data[DOMAIN][entry.entry_id][DATA_IDRAC_REST_CLIENT]

_LOGGER.debug(f"Getting the REST client for {entry.entry_id}")

# TODO figure out how to properly do async stuff in Python lol
info = await hass.async_add_executor_job(target=rest_client.get_device_info)
firmware_version = await hass.async_add_executor_job(target=rest_client.get_firmware_version)
Expand All @@ -35,14 +37,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
serial = info[JSON_SERIAL_NUMBER]

device_info = DeviceInfo(
identifiers={('domain', DOMAIN), ('model', model), ('serial', serial)},
identifiers={('serial', serial)},
name=name,
manufacturer=manufacturer,
model=model,
sw_version=firmware_version,
serial_number=serial
)

_LOGGER.debug(f"Adding new devices to device info {('serial', serial)}")

entities = [IdracCurrentPowerSensor(hass, rest_client, device_info, f"{serial}_{name}_current", name)]

for i, fan in enumerate(thermal_info['Fans']):
Expand Down Expand Up @@ -100,9 +104,7 @@ def update_value(self, new_value: int):


class IdracFanSensor(SensorEntity):
id = 0

def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, id):
def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, index):
self.hass = hass
self.rest = rest

Expand All @@ -119,19 +121,17 @@ def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, id):
self._attr_has_entity_name = True

self._attr_native_value = None
self.id = id
self.index = index

self.rest.register_callback_thermals(self.update_value)

def update_value(self, thermal: dict):
self._attr_native_value = thermal['Fans'][self.id]['Reading']
self._attr_native_value = thermal['Fans'][self.index]['Reading']
self.async_schedule_update_ha_state()


class IdracTempSensor(SensorEntity):
id = 0

def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, id):
def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, index):
self.hass = hass
self.rest = rest

Expand All @@ -148,10 +148,10 @@ def __init__(self, hass, rest: IdracRest, device_info, unique_id, name, id):
self._attr_unique_id = unique_id
self._attr_has_entity_name = True
self._attr_native_value = None
self.id = id
self.index = index

self.rest.register_callback_thermals(self.update_value)

def update_value(self, thermal: dict):
self._attr_native_value = thermal['Temperatures'][self.id]['ReadingCelsius']
self._attr_native_value = thermal['Temperatures'][self.index]['ReadingCelsius']
self.async_schedule_update_ha_state()

0 comments on commit 3c90414

Please sign in to comment.