ha_gehome/custom_components/ge_home/entities/common/ge_erd_number.py

128 lines
3.9 KiB
Python

import logging
from typing import Optional
from gehomesdk.erd.erd_data_type import ErdDataType
from homeassistant.components.number import (
NumberEntity,
NumberDeviceClass,
)
from homeassistant.const import UnitOfTemperature
from gehomesdk import ErdCodeType, ErdCodeClass
from .ge_erd_entity import GeErdEntity
from ...devices import ApplianceApi
_LOGGER = logging.getLogger(__name__)
class GeErdNumber(GeErdEntity, NumberEntity):
"""GE Entity for numbers"""
def __init__(
self,
api: ApplianceApi,
erd_code: ErdCodeType,
erd_override: str = None,
icon_override: str = None,
device_class_override: str = None,
uom_override: str = None,
data_type_override: ErdDataType = None,
min_value: float = 1,
max_value: float = 100,
step_value: float = 1,
mode: str = "auto"
):
super().__init__(api, erd_code, erd_override, icon_override, device_class_override)
self._uom_override = uom_override
self._data_type_override = data_type_override
self._native_min_value = min_value
self._native_max_value = max_value
self._native_step = step_value
self._mode = mode
@property
def native_value(self):
try:
value = self.appliance.get_erd_value(self.erd_code)
return self._convert_value_from_device(value)
except KeyError:
return None
@property
def native_unit_of_measurement(self) -> Optional[str]:
return self._get_uom()
@property
def _data_type(self) -> ErdDataType:
if self._data_type_override is not None:
return self._data_type_override
return self.appliance.get_erd_code_data_type(self.erd_code)
@property
def native_min_value(self) -> float:
return self._convert_value_from_device(self._native_min_value)
@property
def native_max_value(self) -> float:
return self._convert_value_from_device(self._native_max_value)
@property
def native_step(self) -> float:
return self._native_step
@property
def mode(self) -> float:
return self._mode
def _convert_value_from_device(self, value):
"""Convert to expected data type"""
if self._data_type == ErdDataType.INT:
return int(round(value))
else:
return value
def _get_uom(self):
"""Select appropriate units"""
#if we have an override, just use it
if self._uom_override:
return self._uom_override
if self.device_class == NumberDeviceClass.TEMPERATURE:
#NOTE: it appears that the API only sets temperature in Fahrenheit,
#so we'll hard code this UOM instead of using the device configured
#settings
return UnitOfTemperature.FAHRENHEIT
return None
def _get_device_class(self) -> Optional[str]:
if self._device_class_override:
return self._device_class_override
if self.erd_code_class in [
ErdCodeClass.RAW_TEMPERATURE,
ErdCodeClass.NON_ZERO_TEMPERATURE,
]:
return NumberDeviceClass.TEMPERATURE
return None
def _get_icon(self):
if self.erd_code_class == ErdCodeClass.DOOR:
if self.state.lower().endswith("open"):
return "mdi:door-open"
if self.state.lower().endswith("closed"):
return "mdi:door-closed"
return super()._get_icon()
async def async_set_native_value(self, value):
"""Sets the ERD value, assumes that the data type is correct"""
if self._data_type == ErdDataType.INT:
value = int(round(value))
try:
await self.appliance.async_set_erd_value(self.erd_code, value)
except:
_LOGGER.warning(f"Could not set {self.name} to {value}")