diff --git a/homeassistant/components/modbus/base_platform.py b/homeassistant/components/modbus/base_platform.py index 0b612c3ecf5..b321183fd66 100644 --- a/homeassistant/components/modbus/base_platform.py +++ b/homeassistant/components/modbus/base_platform.py @@ -60,17 +60,19 @@ class BasePlatform(Entity): def __init__(self, hub: ModbusHub, entry: dict[str, Any]) -> None: """Initialize the Modbus binary sensor.""" self._hub = hub - self._name = entry[CONF_NAME] self._slave = entry.get(CONF_SLAVE) self._address = int(entry[CONF_ADDRESS]) - self._device_class = entry.get(CONF_DEVICE_CLASS) self._input_type = entry[CONF_INPUT_TYPE] self._value = None - self._available = True self._scan_interval = int(entry[CONF_SCAN_INTERVAL]) - self._available = self._scan_interval == 0 self._call_active = False + self._attr_name = entry[CONF_NAME] + self._attr_should_poll = False + self._attr_device_class = entry.get(CONF_DEVICE_CLASS) + self._attr_available = True + self._attr_unit_of_measurement = None + @abstractmethod async def async_update(self, now=None): """Virtual function to be overwritten.""" @@ -82,26 +84,6 @@ class BasePlatform(Entity): self.hass, self.async_update, timedelta(seconds=self._scan_interval) ) - @property - def name(self): - """Return the name of the sensor.""" - return self._name - - @property - def should_poll(self): - """Return True if entity has to be polled for state.""" - return False - - @property - def device_class(self) -> str | None: - """Return the device class of the sensor.""" - return self._device_class - - @property - def available(self) -> bool: - """Return True if entity is available.""" - return self._available - class BaseStructPlatform(BasePlatform, RestoreEntity): """Base class representing a sensor/climate.""" @@ -229,11 +211,11 @@ class BaseSwitch(BasePlatform, RestoreEntity): self._slave, self._address, command, self._write_type ) if result is None: - self._available = False + self._attr_available = False self.async_write_ha_state() return - self._available = True + self._attr_available = True if not self._verify_active: self._is_on = command == self.command_on self.async_write_ha_state() @@ -253,7 +235,7 @@ class BaseSwitch(BasePlatform, RestoreEntity): # remark "now" is a dummy parameter to avoid problems with # async_track_time_interval if not self._verify_active: - self._available = True + self._attr_available = True self.async_write_ha_state() return @@ -266,11 +248,11 @@ class BaseSwitch(BasePlatform, RestoreEntity): ) self._call_active = False if result is None: - self._available = False + self._attr_available = False self.async_write_ha_state() return - self._available = True + self._attr_available = True if self._verify_type == CALL_TYPE_COIL: self._is_on = bool(result.bits[0] & 1) else: diff --git a/homeassistant/components/modbus/binary_sensor.py b/homeassistant/components/modbus/binary_sensor.py index 0188210be8a..ac635c76275 100644 --- a/homeassistant/components/modbus/binary_sensor.py +++ b/homeassistant/components/modbus/binary_sensor.py @@ -64,10 +64,10 @@ class ModbusBinarySensor(BasePlatform, RestoreEntity, BinarySensorEntity): ) self._call_active = False if result is None: - self._available = False + self._attr_available = False self.async_write_ha_state() return self._value = result.bits[0] & 1 - self._available = True + self._attr_available = True self.async_write_ha_state() diff --git a/homeassistant/components/modbus/climate.py b/homeassistant/components/modbus/climate.py index e8f281bdd1f..1353828b926 100644 --- a/homeassistant/components/modbus/climate.py +++ b/homeassistant/components/modbus/climate.py @@ -76,76 +76,37 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity): """Initialize the modbus thermostat.""" super().__init__(hub, config) self._target_temperature_register = config[CONF_TARGET_TEMP] - self._target_temperature = None - self._current_temperature = None - self._structure = config[CONF_STRUCTURE] self._unit = config[CONF_TEMPERATURE_UNIT] - self._max_temp = config[CONF_MAX_TEMP] - self._min_temp = config[CONF_MIN_TEMP] - self._temp_step = config[CONF_STEP] + self._structure = config[CONF_STRUCTURE] + + self._attr_supported_features = SUPPORT_TARGET_TEMPERATURE + self._attr_hvac_mode = HVAC_MODE_AUTO + self._attr_hvac_modes = [HVAC_MODE_AUTO] + self._attr_current_temperature = None + self._attr_target_temperature = None + self._attr_temperature_unit = ( + TEMP_FAHRENHEIT if self._unit == "F" else TEMP_CELSIUS + ) + self._attr_precision = ( + PRECISION_TENTHS if self._precision >= 1 else PRECISION_WHOLE + ) + self._attr_min_temp = config[CONF_MIN_TEMP] + self._attr_max_temp = config[CONF_MAX_TEMP] + self._attr_target_temperature_step = config[CONF_TARGET_TEMP] + self._attr_target_temperature_step = config[CONF_STEP] async def async_added_to_hass(self): """Handle entity which will be added.""" await self.async_base_added_to_hass() state = await self.async_get_last_state() if state and state.attributes.get(ATTR_TEMPERATURE): - self._target_temperature = float(state.attributes[ATTR_TEMPERATURE]) - - @property - def supported_features(self): - """Return the list of supported features.""" - return SUPPORT_TARGET_TEMPERATURE - - @property - def hvac_mode(self): - """Return the current HVAC mode.""" - return HVAC_MODE_AUTO - - @property - def hvac_modes(self): - """Return the possible HVAC modes.""" - return [HVAC_MODE_AUTO] + self._attr_target_temperature = float(state.attributes[ATTR_TEMPERATURE]) async def async_set_hvac_mode(self, hvac_mode: str) -> None: """Set new target hvac mode.""" # Home Assistant expects this method. # We'll keep it here to avoid getting exceptions. - @property - def current_temperature(self): - """Return the current temperature.""" - return self._current_temperature - - @property - def target_temperature(self): - """Return the target temperature.""" - return self._target_temperature - - @property - def temperature_unit(self): - """Return the unit of measurement.""" - return TEMP_FAHRENHEIT if self._unit == "F" else TEMP_CELSIUS - - @property - def precision(self) -> float: - """Return the precision of the system.""" - return PRECISION_TENTHS if self._precision >= 1 else PRECISION_WHOLE - - @property - def min_temp(self): - """Return the minimum temperature.""" - return self._min_temp - - @property - def max_temp(self): - """Return the maximum temperature.""" - return self._max_temp - - @property - def target_temperature_step(self): - """Return the supported step of target temperature.""" - return self._temp_step - async def async_set_temperature(self, **kwargs): """Set new target temperature.""" if ATTR_TEMPERATURE not in kwargs: @@ -174,7 +135,7 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity): registers, CALL_TYPE_WRITE_REGISTERS, ) - self._available = result is not None + self._attr_available = result is not None await self.async_update() async def async_update(self, now=None): @@ -186,10 +147,10 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity): if self._call_active: return self._call_active = True - self._target_temperature = await self._async_read_register( + self._attr_target_temperature = await self._async_read_register( CALL_TYPE_REGISTER_HOLDING, self._target_temperature_register ) - self._current_temperature = await self._async_read_register( + self._attr_current_temperature = await self._async_read_register( self._input_type, self._address ) self._call_active = False @@ -201,12 +162,12 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity): self._slave, register, self._count, register_type ) if result is None: - self._available = False + self._attr_available = False return -1 self.unpack_structure_result(result.registers) - self._available = True + self._attr_available = True if self._value is None: return None diff --git a/homeassistant/components/modbus/cover.py b/homeassistant/components/modbus/cover.py index bd150434dc1..98a352f218a 100644 --- a/homeassistant/components/modbus/cover.py +++ b/homeassistant/components/modbus/cover.py @@ -73,6 +73,8 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity): self._status_register = config.get(CONF_STATUS_REGISTER) self._status_register_type = config[CONF_STATUS_REGISTER_TYPE] + self._attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE + # If we read cover status from coil, and not from optional status register, # we interpret boolean value False as closed cover, and value True as open cover. # Intermediate states are not supported in such a setup. @@ -109,11 +111,6 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity): } self._value = convert[state.state] - @property - def supported_features(self): - """Flag supported features.""" - return SUPPORT_OPEN | SUPPORT_CLOSE - @property def is_opening(self): """Return if the cover is opening or not.""" @@ -134,7 +131,7 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity): result = await self._hub.async_pymodbus_call( self._slave, self._write_address, self._state_open, self._write_type ) - self._available = result is not None + self._attr_available = result is not None await self.async_update() async def async_close_cover(self, **kwargs: Any) -> None: @@ -142,7 +139,7 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity): result = await self._hub.async_pymodbus_call( self._slave, self._write_address, self._state_closed, self._write_type ) - self._available = result is not None + self._attr_available = result is not None await self.async_update() async def async_update(self, now=None): @@ -158,10 +155,10 @@ class ModbusCover(BasePlatform, CoverEntity, RestoreEntity): ) self._call_active = False if result is None: - self._available = False + self._attr_available = False self.async_write_ha_state() return None - self._available = True + self._attr_available = True if self._input_type == CALL_TYPE_COIL: self._value = bool(result.bits[0] & 1) else: diff --git a/homeassistant/components/modbus/sensor.py b/homeassistant/components/modbus/sensor.py index 1f2b5e32f6f..e969fa23a65 100644 --- a/homeassistant/components/modbus/sensor.py +++ b/homeassistant/components/modbus/sensor.py @@ -47,7 +47,7 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity): ) -> None: """Initialize the modbus register sensor.""" super().__init__(hub, entry) - self._unit_of_measurement = entry.get(CONF_UNIT_OF_MEASUREMENT) + self._attr_unit_of_measurement = entry.get(CONF_UNIT_OF_MEASUREMENT) async def async_added_to_hass(self): """Handle entity which will be added.""" @@ -61,11 +61,6 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity): """Return the state of the sensor.""" return self._value - @property - def unit_of_measurement(self): - """Return the unit of measurement.""" - return self._unit_of_measurement - async def async_update(self, now=None): """Update the state of the sensor.""" # remark "now" is a dummy parameter to avoid problems with @@ -74,10 +69,10 @@ class ModbusRegisterSensor(BaseStructPlatform, RestoreEntity, SensorEntity): self._slave, self._address, self._count, self._input_type ) if result is None: - self._available = False + self._attr_available = False self.async_write_ha_state() return self.unpack_structure_result(result.registers) - self._available = True + self._attr_available = True self.async_write_ha_state()