diff --git a/custom_components/smartbox/__init__.py b/custom_components/smartbox/__init__.py index 5850ce0..1600953 100644 --- a/custom_components/smartbox/__init__.py +++ b/custom_components/smartbox/__init__.py @@ -6,6 +6,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant +from homeassistant.helpers.discovery import async_load_platform from smartbox import __version__ as SMARTBOX_VERSION @@ -133,9 +134,7 @@ async def async_setup(hass: HomeAssistant, config: dict) -> bool: if hass.data[DOMAIN][SMARTBOX_DEVICES]: for component in PLATFORMS: - await hass.helpers.discovery.async_load_platform( - component, DOMAIN, {}, config - ) + await async_load_platform(hass, component, DOMAIN, {}, config) _LOGGER.debug("Finished setting up Smartbox integration") diff --git a/custom_components/smartbox/climate.py b/custom_components/smartbox/climate.py index 56ea541..5e7efcd 100644 --- a/custom_components/smartbox/climate.py +++ b/custom_components/smartbox/climate.py @@ -11,7 +11,7 @@ from homeassistant.const import ( ATTR_LOCKED, ATTR_TEMPERATURE, - TEMP_CELSIUS, + UnitOfTemperature, ) from homeassistant.core import HomeAssistant import logging @@ -75,11 +75,19 @@ def __init__(self, node: Union[MagicMock, SmartboxNode]) -> None: self._node = node self._status: Dict[str, Any] = {} self._available = False # unavailable until we get an update + self._enable_turn_on_off_backwards_compatibility = False self._supported_features = ( - ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE + ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE | ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON ) _LOGGER.debug(f"Created node {self.name} unique_id={self.unique_id}") + async def async_turn_off(self) -> None: + await self.async_set_hvac_mode(HVACMode.OFF) + + async def async_turn_on(self) -> None: + await self.async_set_hvac_mode(HVACMode.AUTO) + + @property def unique_id(self) -> str: """Return Unique ID string.""" @@ -108,7 +116,7 @@ def temperature_unit(self) -> str: return unit else: return ( - TEMP_CELSIUS # climate sensors need a temperature unit on construction + UnitOfTemperature.CELSIUS # climate sensors need a temperature unit on construction ) @property diff --git a/custom_components/smartbox/model.py b/custom_components/smartbox/model.py index 99eb59a..69e8f55 100644 --- a/custom_components/smartbox/model.py +++ b/custom_components/smartbox/model.py @@ -2,19 +2,21 @@ import logging from homeassistant.const import ( - TEMP_CELSIUS, - TEMP_FAHRENHEIT, + UnitOfTemperature, +) + +from homeassistant.components.climate import ( + HVACMode, ) from homeassistant.components.climate.const import ( - HVAC_MODE_AUTO, - HVAC_MODE_HEAT, - HVAC_MODE_OFF, PRESET_ACTIVITY, PRESET_AWAY, PRESET_COMFORT, PRESET_ECO, PRESET_HOME, ) + + from homeassistant.core import HomeAssistant from smartbox import Session, UpdateManager from typing import Any, cast, Dict, List, Union @@ -246,9 +248,9 @@ def get_temperature_unit(status): return None unit = status["units"] if unit == "C": - return TEMP_CELSIUS + return UnitOfTemperature.CELSIUS elif unit == "F": - return TEMP_FAHRENHEIT + return UnitOfTemperature.FAHRENHEIT else: raise ValueError(f"Unknown temp unit {unit}") @@ -382,21 +384,21 @@ def set_temperature_args( def get_hvac_mode(node_type: str, status: Dict[str, Any]) -> str: _check_status_key("mode", node_type, status) if status["mode"] == "off": - return HVAC_MODE_OFF + return HVACMode.OFF elif node_type == HEATER_NODE_TYPE_HTR_MOD and not status["on"]: - return HVAC_MODE_OFF + return HVACMode.OFF elif status["mode"] == "manual": - return HVAC_MODE_HEAT + return HVACMode.HEAT elif status["mode"] == "auto": - return HVAC_MODE_AUTO + return HVACMode.AUTO elif status["mode"] == "modified_auto": # This occurs when the temperature is modified while in auto mode. # Mapping it to auto seems to make this most sense - return HVAC_MODE_AUTO + return HVACMode.AUTO elif status["mode"] == "self_learn": - return HVAC_MODE_AUTO + return HVACMode.AUTO elif status["mode"] == "presence": - return HVAC_MODE_AUTO + return HVACMode.AUTO else: _LOGGER.error(f"Unknown smartbox node mode {status['mode']}") raise ValueError(f"Unknown smartbox node mode {status['mode']}") @@ -406,9 +408,9 @@ def set_hvac_mode_args( node_type: str, status: Dict[str, Any], hvac_mode: str ) -> Dict[str, Any]: if node_type == HEATER_NODE_TYPE_HTR_MOD: - if hvac_mode == HVAC_MODE_OFF: + if hvac_mode == HVACMode.OFF: return {"on": False} - elif hvac_mode == HVAC_MODE_HEAT: + elif hvac_mode == HVACMode.HEAT: # We need to pass these status keys on when setting the mode required_status_keys = ["selected_temp"] for key in required_status_keys: @@ -417,16 +419,16 @@ def set_hvac_mode_args( hvac_mode_args["on"] = True hvac_mode_args["mode"] = "manual" return hvac_mode_args - elif hvac_mode == HVAC_MODE_AUTO: + elif hvac_mode == HVACMode.AUTO: return {"on": True, "mode": "auto"} else: raise ValueError(f"Unsupported hvac mode {hvac_mode}") else: - if hvac_mode == HVAC_MODE_OFF: + if hvac_mode == HVACMode.OFF: return {"mode": "off"} - elif hvac_mode == HVAC_MODE_HEAT: + elif hvac_mode == HVACMode.HEAT: return {"mode": "manual"} - elif hvac_mode == HVAC_MODE_AUTO: + elif hvac_mode == HVACMode.AUTO: return {"mode": "auto"} else: raise ValueError(f"Unsupported hvac mode {hvac_mode}") @@ -492,7 +494,7 @@ def set_preset_mode_status_update( assert preset_mode != PRESET_HOME and preset_mode != PRESET_AWAY if preset_mode == PRESET_SCHEDULE: - return set_hvac_mode_args(node_type, status, HVAC_MODE_AUTO) + return set_hvac_mode_args(node_type, status, HVACMode.AUTO) elif preset_mode == PRESET_SELF_LEARN: return {"on": True, "mode": "self_learn"} elif preset_mode == PRESET_ACTIVITY: diff --git a/custom_components/smartbox/sensor.py b/custom_components/smartbox/sensor.py index 1353a8c..5133a15 100644 --- a/custom_components/smartbox/sensor.py +++ b/custom_components/smartbox/sensor.py @@ -1,18 +1,14 @@ from datetime import datetime, timedelta from homeassistant.const import ( ATTR_LOCKED, - DEVICE_CLASS_BATTERY, - DEVICE_CLASS_ENERGY, - DEVICE_CLASS_POWER, - DEVICE_CLASS_POWER_FACTOR, - DEVICE_CLASS_TEMPERATURE, - ENERGY_WATT_HOUR, + UnitOfEnergy, PERCENTAGE, - POWER_WATT, + UnitOfPower, ) from homeassistant.components.sensor import ( SensorEntity, SensorStateClass, + SensorDeviceClass, ) from homeassistant.core import HomeAssistant import logging @@ -134,7 +130,7 @@ def time_since_last_update(self) -> Optional[timedelta]: class TemperatureSensor(SmartboxSensorBase): """Smartbox heater temperature sensor""" - device_class = DEVICE_CLASS_TEMPERATURE + device_class = SensorDeviceClass.TEMPERATURE state_class = SensorStateClass.MEASUREMENT def __init__(self, node: Union[SmartboxNode, MagicMock]) -> None: @@ -167,8 +163,8 @@ class PowerSensor(SmartboxSensorBase): sensor. """ - device_class = DEVICE_CLASS_POWER - native_unit_of_measurement = POWER_WATT + device_class = SensorDeviceClass.POWER + native_unit_of_measurement = UnitOfPower.WATT state_class = SensorStateClass.MEASUREMENT def __init__(self, node: Union[SmartboxNode, MagicMock]) -> None: @@ -197,7 +193,7 @@ class DutyCycleSensor(SmartboxSensorBase): Represents the duty cycle for the heater. """ - device_class = DEVICE_CLASS_POWER_FACTOR + device_class = SensorDeviceClass.POWER_FACTOR native_unit_of_measurement = PERCENTAGE state_class = SensorStateClass.MEASUREMENT @@ -223,8 +219,8 @@ class EnergySensor(SmartboxSensorBase): Represents the energy consumed by the heater. """ - device_class = DEVICE_CLASS_ENERGY - native_unit_of_measurement = ENERGY_WATT_HOUR + device_class = SensorDeviceClass.ENERGY + native_unit_of_measurement = UnitOfEnergy.WATT_HOUR state_class = SensorStateClass.TOTAL def __init__(self, node: Union[SmartboxNode, MagicMock]) -> None: @@ -257,7 +253,7 @@ def native_value(self) -> float | None: class ChargeLevelSensor(SmartboxSensorBase): """Smartbox storage heater charge level sensor""" - device_class = DEVICE_CLASS_BATTERY + device_class = SensorDeviceClass.BATTERY native_unit_of_measurement = PERCENTAGE state_class = SensorStateClass.MEASUREMENT @@ -275,3 +271,4 @@ def unique_id(self) -> str: @property def native_value(self) -> int: return self._status["charge_level"] +