diff --git a/homeassistant/components/weather/__init__.py b/homeassistant/components/weather/__init__.py index 05a2e725e4aa..0d72dbb825e9 100644 --- a/homeassistant/components/weather/__init__.py +++ b/homeassistant/components/weather/__init__.py @@ -274,35 +274,8 @@ class WeatherEntity(Entity, PostInit): _attr_cloud_coverage: int | None = None _attr_uv_index: float | None = None _attr_precision: float - _attr_pressure: None = ( - None # Provide backwards compatibility. Use _attr_native_pressure - ) - _attr_pressure_unit: None = ( - None # Provide backwards compatibility. Use _attr_native_pressure_unit - ) _attr_state: None = None - _attr_temperature: None = ( - None # Provide backwards compatibility. Use _attr_native_temperature - ) - _attr_temperature_unit: None = ( - None # Provide backwards compatibility. Use _attr_native_temperature_unit - ) - _attr_visibility: None = ( - None # Provide backwards compatibility. Use _attr_native_visibility - ) - _attr_visibility_unit: None = ( - None # Provide backwards compatibility. Use _attr_native_visibility_unit - ) - _attr_precipitation_unit: None = ( - None # Provide backwards compatibility. Use _attr_native_precipitation_unit - ) _attr_wind_bearing: float | str | None = None - _attr_wind_speed: None = ( - None # Provide backwards compatibility. Use _attr_native_wind_speed - ) - _attr_wind_speed_unit: None = ( - None # Provide backwards compatibility. Use _attr_native_wind_speed_unit - ) _attr_native_pressure: float | None = None _attr_native_pressure_unit: str | None = None @@ -322,8 +295,6 @@ class WeatherEntity(Entity, PostInit): list[Callable[[list[JsonValueType] | None], None]], ] __weather_legacy_forecast: bool = False - __weather_legacy_forecast_reported: bool = False - __report_issue: str _weather_option_temperature_unit: str | None = None _weather_option_pressure_unit: str | None = None @@ -338,55 +309,6 @@ class WeatherEntity(Entity, PostInit): def __init_subclass__(cls, **kwargs: Any) -> None: """Post initialisation processing.""" super().__init_subclass__(**kwargs) - - _reported = False - if any( - method in cls.__dict__ - for method in ( - "_attr_temperature", - "temperature", - "_attr_temperature_unit", - "temperature_unit", - "_attr_pressure", - "pressure", - "_attr_pressure_unit", - "pressure_unit", - "_attr_wind_speed", - "wind_speed", - "_attr_wind_speed_unit", - "wind_speed_unit", - "_attr_visibility", - "visibility", - "_attr_visibility_unit", - "visibility_unit", - "_attr_precipitation_unit", - "precipitation_unit", - ) - ): - if _reported is False: - module = inspect.getmodule(cls) - _reported = True - if ( - module - and module.__file__ - and "custom_components" in module.__file__ - ): - report_issue = "report it to the custom integration author." - else: - report_issue = ( - "create a bug report at " - "https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue" - ) - _LOGGER.warning( - ( - "%s::%s is overriding deprecated methods on an instance of " - "WeatherEntity, this is not valid and will be unsupported " - "from Home Assistant 2023.1. Please %s" - ), - cls.__module__, - cls.__name__, - report_issue, - ) if any( method in cls.__dict__ for method in ("_attr_forecast", "forecast") ) and not any( @@ -453,29 +375,14 @@ class WeatherEntity(Entity, PostInit): """Return the apparent temperature in native units.""" return self._attr_native_temperature - @final - @property - def temperature(self) -> float | None: - """Return the temperature for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_temperature - @property def native_temperature(self) -> float | None: """Return the temperature in native units.""" - if (temperature := self.temperature) is not None: - return temperature - return self._attr_native_temperature @property def native_temperature_unit(self) -> str | None: """Return the native unit of measurement for temperature.""" - if (temperature_unit := self.temperature_unit) is not None: - return temperature_unit - return self._attr_native_temperature_unit @property @@ -483,15 +390,6 @@ class WeatherEntity(Entity, PostInit): """Return the dew point temperature in native units.""" return self._attr_native_dew_point - @final - @property - def temperature_unit(self) -> str | None: - """Return the temperature unit for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_temperature_unit - @final @property def _default_temperature_unit(self) -> str: @@ -515,40 +413,16 @@ class WeatherEntity(Entity, PostInit): return self._default_temperature_unit - @final - @property - def pressure(self) -> float | None: - """Return the pressure for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_pressure - @property def native_pressure(self) -> float | None: """Return the pressure in native units.""" - if (pressure := self.pressure) is not None: - return pressure - return self._attr_native_pressure @property def native_pressure_unit(self) -> str | None: """Return the native unit of measurement for pressure.""" - if (pressure_unit := self.pressure_unit) is not None: - return pressure_unit - return self._attr_native_pressure_unit - @final - @property - def pressure_unit(self) -> str | None: - """Return the pressure unit for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_pressure_unit - @final @property def _default_pressure_unit(self) -> str: @@ -584,40 +458,16 @@ class WeatherEntity(Entity, PostInit): """Return the wind gust speed in native units.""" return self._attr_native_wind_gust_speed - @final - @property - def wind_speed(self) -> float | None: - """Return the wind_speed for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_wind_speed - @property def native_wind_speed(self) -> float | None: """Return the wind speed in native units.""" - if (wind_speed := self.wind_speed) is not None: - return wind_speed - return self._attr_native_wind_speed @property def native_wind_speed_unit(self) -> str | None: """Return the native unit of measurement for wind speed.""" - if (wind_speed_unit := self.wind_speed_unit) is not None: - return wind_speed_unit - return self._attr_native_wind_speed_unit - @final - @property - def wind_speed_unit(self) -> str | None: - """Return the wind_speed unit for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_wind_speed_unit - @final @property def _default_wind_speed_unit(self) -> str: @@ -663,40 +513,16 @@ class WeatherEntity(Entity, PostInit): """Return the UV index.""" return self._attr_uv_index - @final - @property - def visibility(self) -> float | None: - """Return the visibility for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_visibility - @property def native_visibility(self) -> float | None: """Return the visibility in native units.""" - if (visibility := self.visibility) is not None: - return visibility - return self._attr_native_visibility @property def native_visibility_unit(self) -> str | None: """Return the native unit of measurement for visibility.""" - if (visibility_unit := self.visibility_unit) is not None: - return visibility_unit - return self._attr_native_visibility_unit - @final - @property - def visibility_unit(self) -> str | None: - """Return the visibility unit for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_visibility_unit - @final @property def _default_visibility_unit(self) -> str: @@ -743,20 +569,8 @@ class WeatherEntity(Entity, PostInit): @property def native_precipitation_unit(self) -> str | None: """Return the native unit of measurement for accumulated precipitation.""" - if (precipitation_unit := self.precipitation_unit) is not None: - return precipitation_unit - return self._attr_native_precipitation_unit - @final - @property - def precipitation_unit(self) -> str | None: - """Return the precipitation unit for backward compatibility. - - Should not be set by integrations. - """ - return self._attr_precipitation_unit - @final @property def _default_precipitation_unit(self) -> str: diff --git a/tests/components/weather/test_init.py b/tests/components/weather/test_init.py index feef335bec90..db3a18db9147 100644 --- a/tests/components/weather/test_init.py +++ b/tests/components/weather/test_init.py @@ -15,7 +15,6 @@ from homeassistant.components.weather import ( ATTR_FORECAST_TEMP, ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_UV_INDEX, - ATTR_FORECAST_WIND_BEARING, ATTR_FORECAST_WIND_GUST_SPEED, ATTR_FORECAST_WIND_SPEED, ATTR_WEATHER_APPARENT_TEMPERATURE, @@ -46,7 +45,6 @@ from homeassistant.components.weather.const import ( ATTR_WEATHER_HUMIDITY, ) from homeassistant.const import ( - ATTR_FRIENDLY_NAME, PRECISION_HALVES, PRECISION_TENTHS, PRECISION_WHOLE, @@ -128,31 +126,6 @@ class MockWeatherEntityPrecision(WeatherEntity): self._attr_precision = PRECISION_HALVES -class MockWeatherEntityCompat(WeatherEntity): - """Mock a Weather Entity using old attributes.""" - - def __init__(self) -> None: - """Initiate Entity.""" - super().__init__() - self._attr_condition = ATTR_CONDITION_SUNNY - self._attr_precipitation_unit = UnitOfLength.MILLIMETERS - self._attr_pressure = 10 - self._attr_pressure_unit = UnitOfPressure.HPA - self._attr_temperature = 20 - self._attr_temperature_unit = UnitOfTemperature.CELSIUS - self._attr_visibility = 30 - self._attr_visibility_unit = UnitOfLength.KILOMETERS - self._attr_wind_speed = 3 - self._attr_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND - self._attr_forecast = [ - Forecast( - datetime=datetime(2022, 6, 20, 0, 00, 00, tzinfo=dt_util.UTC), - precipitation=1, - temperature=20, - ) - ] - - @pytest.mark.parametrize( "native_unit", (UnitOfTemperature.FAHRENHEIT, UnitOfTemperature.CELSIUS) ) @@ -775,219 +748,6 @@ async def test_custom_units( ) -async def test_backwards_compatibility( - hass: HomeAssistant, enable_custom_integrations: None -) -> None: - """Test backwards compatibility.""" - wind_speed_value = 5 - wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND - pressure_value = 110000 - pressure_unit = UnitOfPressure.PA - temperature_value = 20 - temperature_unit = UnitOfTemperature.CELSIUS - visibility_value = 11 - visibility_unit = UnitOfLength.KILOMETERS - precipitation_value = 1 - precipitation_unit = UnitOfLength.MILLIMETERS - - hass.config.units = METRIC_SYSTEM - - platform: WeatherPlatform = getattr(hass.components, "test.weather") - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecastCompat( - name="Test", - condition=ATTR_CONDITION_SUNNY, - temperature=temperature_value, - temperature_unit=temperature_unit, - wind_speed=wind_speed_value, - wind_speed_unit=wind_speed_unit, - pressure=pressure_value, - pressure_unit=pressure_unit, - visibility=visibility_value, - visibility_unit=visibility_unit, - precipitation=precipitation_value, - precipitation_unit=precipitation_unit, - unique_id="very_unique", - ) - ) - platform.ENTITIES.append( - platform.MockWeatherMockForecastCompat( - name="Test2", - condition=ATTR_CONDITION_SUNNY, - temperature=temperature_value, - temperature_unit=temperature_unit, - wind_speed=wind_speed_value, - pressure=pressure_value, - visibility=visibility_value, - precipitation=precipitation_value, - unique_id="very_unique2", - ) - ) - - entity0 = platform.ENTITIES[0] - entity1 = platform.ENTITIES[1] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test"}} - ) - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test2"}} - ) - await hass.async_block_till_done() - - state = hass.states.get(entity0.entity_id) - forecast = state.attributes[ATTR_FORECAST][0] - state1 = hass.states.get(entity1.entity_id) - forecast1 = state1.attributes[ATTR_FORECAST][0] - - assert float(state.attributes[ATTR_WEATHER_WIND_SPEED]) == pytest.approx( - wind_speed_value * 3.6 - ) - assert ( - state.attributes[ATTR_WEATHER_WIND_SPEED_UNIT] - == UnitOfSpeed.KILOMETERS_PER_HOUR - ) - assert float(state.attributes[ATTR_WEATHER_TEMPERATURE]) == pytest.approx( - temperature_value, rel=0.1 - ) - assert state.attributes[ATTR_WEATHER_TEMPERATURE_UNIT] == UnitOfTemperature.CELSIUS - assert float(state.attributes[ATTR_WEATHER_PRESSURE]) == pytest.approx( - pressure_value / 100 - ) - assert state.attributes[ATTR_WEATHER_PRESSURE_UNIT] == UnitOfPressure.HPA - assert float(state.attributes[ATTR_WEATHER_VISIBILITY]) == pytest.approx( - visibility_value - ) - assert state.attributes[ATTR_WEATHER_VISIBILITY_UNIT] == UnitOfLength.KILOMETERS - assert float(forecast[ATTR_FORECAST_PRECIPITATION]) == pytest.approx( - precipitation_value, rel=1e-2 - ) - assert state.attributes[ATTR_WEATHER_PRECIPITATION_UNIT] == UnitOfLength.MILLIMETERS - - assert float(state1.attributes[ATTR_WEATHER_WIND_SPEED]) == pytest.approx( - wind_speed_value - ) - assert ( - state1.attributes[ATTR_WEATHER_WIND_SPEED_UNIT] - == UnitOfSpeed.KILOMETERS_PER_HOUR - ) - assert float(state1.attributes[ATTR_WEATHER_TEMPERATURE]) == pytest.approx( - temperature_value, rel=0.1 - ) - assert state1.attributes[ATTR_WEATHER_TEMPERATURE_UNIT] == UnitOfTemperature.CELSIUS - assert float(state1.attributes[ATTR_WEATHER_PRESSURE]) == pytest.approx( - pressure_value - ) - assert state1.attributes[ATTR_WEATHER_PRESSURE_UNIT] == UnitOfPressure.HPA - assert float(state1.attributes[ATTR_WEATHER_VISIBILITY]) == pytest.approx( - visibility_value - ) - assert state1.attributes[ATTR_WEATHER_VISIBILITY_UNIT] == UnitOfLength.KILOMETERS - assert float(forecast1[ATTR_FORECAST_PRECIPITATION]) == pytest.approx( - precipitation_value, rel=1e-2 - ) - assert ( - state1.attributes[ATTR_WEATHER_PRECIPITATION_UNIT] == UnitOfLength.MILLIMETERS - ) - - -async def test_backwards_compatibility_convert_values( - hass: HomeAssistant, enable_custom_integrations: None -) -> None: - """Test backward compatibility for converting values.""" - wind_speed_value = 5 - wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND - pressure_value = 110000 - pressure_unit = UnitOfPressure.PA - temperature_value = 20 - temperature_unit = UnitOfTemperature.CELSIUS - visibility_value = 11 - visibility_unit = UnitOfLength.KILOMETERS - precipitation_value = 1 - precipitation_unit = UnitOfLength.MILLIMETERS - - hass.config.units = US_CUSTOMARY_SYSTEM - - platform: WeatherPlatform = getattr(hass.components, "test.weather") - platform.init(empty=True) - platform.ENTITIES.append( - platform.MockWeatherMockForecastCompat( - name="Test", - condition=ATTR_CONDITION_SUNNY, - temperature=temperature_value, - temperature_unit=temperature_unit, - wind_speed=wind_speed_value, - wind_speed_unit=wind_speed_unit, - pressure=pressure_value, - pressure_unit=pressure_unit, - visibility=visibility_value, - visibility_unit=visibility_unit, - precipitation=precipitation_value, - precipitation_unit=precipitation_unit, - unique_id="very_unique", - ) - ) - - entity0 = platform.ENTITIES[0] - assert await async_setup_component( - hass, "weather", {"weather": {"platform": "test"}} - ) - await hass.async_block_till_done() - - state = hass.states.get(entity0.entity_id) - - expected_wind_speed = round( - SpeedConverter.convert( - wind_speed_value, wind_speed_unit, UnitOfSpeed.MILES_PER_HOUR - ), - ROUNDING_PRECISION, - ) - expected_temperature = TemperatureConverter.convert( - temperature_value, temperature_unit, UnitOfTemperature.FAHRENHEIT - ) - expected_pressure = round( - PressureConverter.convert(pressure_value, pressure_unit, UnitOfPressure.INHG), - ROUNDING_PRECISION, - ) - expected_visibility = round( - DistanceConverter.convert( - visibility_value, visibility_unit, UnitOfLength.MILES - ), - ROUNDING_PRECISION, - ) - expected_precipitation = round( - DistanceConverter.convert( - precipitation_value, precipitation_unit, UnitOfLength.INCHES - ), - ROUNDING_PRECISION, - ) - - assert state.attributes == { - ATTR_FORECAST: [ - { - ATTR_FORECAST_PRECIPITATION: pytest.approx( - expected_precipitation, rel=0.1 - ), - ATTR_FORECAST_PRESSURE: pytest.approx(expected_pressure, rel=0.1), - ATTR_FORECAST_TEMP: pytest.approx(expected_temperature, rel=0.1), - ATTR_FORECAST_TEMP_LOW: pytest.approx(expected_temperature, rel=0.1), - ATTR_FORECAST_WIND_BEARING: None, - ATTR_FORECAST_WIND_SPEED: pytest.approx(expected_wind_speed, rel=0.1), - } - ], - ATTR_FRIENDLY_NAME: "Test", - ATTR_WEATHER_PRECIPITATION_UNIT: UnitOfLength.INCHES, - ATTR_WEATHER_PRESSURE: pytest.approx(expected_pressure, rel=0.1), - ATTR_WEATHER_PRESSURE_UNIT: UnitOfPressure.INHG, - ATTR_WEATHER_TEMPERATURE: pytest.approx(expected_temperature, rel=0.1), - ATTR_WEATHER_TEMPERATURE_UNIT: UnitOfTemperature.FAHRENHEIT, - ATTR_WEATHER_VISIBILITY: pytest.approx(expected_visibility, rel=0.1), - ATTR_WEATHER_VISIBILITY_UNIT: UnitOfLength.MILES, - ATTR_WEATHER_WIND_SPEED: pytest.approx(expected_wind_speed, rel=0.1), - ATTR_WEATHER_WIND_SPEED_UNIT: UnitOfSpeed.MILES_PER_HOUR, - } - - async def test_backwards_compatibility_round_temperature(hass: HomeAssistant) -> None: """Test backward compatibility for rounding temperature.""" @@ -1020,47 +780,6 @@ async def test_attr(hass: HomeAssistant) -> None: assert weather._wind_speed_unit == UnitOfSpeed.KILOMETERS_PER_HOUR -async def test_attr_compatibility(hass: HomeAssistant) -> None: - """Test the _attr attributes in compatibility mode.""" - - weather = MockWeatherEntityCompat() - weather.hass = hass - - assert weather.condition == ATTR_CONDITION_SUNNY - assert weather._precipitation_unit == UnitOfLength.MILLIMETERS - assert weather.pressure == 10 - assert weather._pressure_unit == UnitOfPressure.HPA - assert weather.temperature == 20 - assert weather._temperature_unit == UnitOfTemperature.CELSIUS - assert weather.visibility == 30 - assert weather.visibility_unit == UnitOfLength.KILOMETERS - assert weather.wind_speed == 3 - assert weather._wind_speed_unit == UnitOfSpeed.KILOMETERS_PER_HOUR - - forecast_entry = [ - Forecast( - datetime=datetime(2022, 6, 20, 0, 00, 00, tzinfo=dt_util.UTC), - precipitation=1, - temperature=20, - ) - ] - - assert weather.forecast == forecast_entry - - assert weather.state_attributes == { - ATTR_FORECAST: forecast_entry, - ATTR_WEATHER_PRESSURE: 10.0, - ATTR_WEATHER_PRESSURE_UNIT: UnitOfPressure.HPA, - ATTR_WEATHER_TEMPERATURE: 20.0, - ATTR_WEATHER_TEMPERATURE_UNIT: UnitOfTemperature.CELSIUS, - ATTR_WEATHER_VISIBILITY: 30.0, - ATTR_WEATHER_VISIBILITY_UNIT: UnitOfLength.KILOMETERS, - ATTR_WEATHER_WIND_SPEED: 3.0 * 3.6, - ATTR_WEATHER_WIND_SPEED_UNIT: UnitOfSpeed.KILOMETERS_PER_HOUR, - ATTR_WEATHER_PRECIPITATION_UNIT: UnitOfLength.MILLIMETERS, - } - - async def test_precision_for_temperature(hass: HomeAssistant) -> None: """Test the precision for temperature.""" diff --git a/tests/testing_config/custom_components/test/weather.py b/tests/testing_config/custom_components/test/weather.py index 405b7b7d8227..84864c1dbb23 100644 --- a/tests/testing_config/custom_components/test/weather.py +++ b/tests/testing_config/custom_components/test/weather.py @@ -18,13 +18,8 @@ from homeassistant.components.weather import ( ATTR_FORECAST_NATIVE_TEMP_LOW, ATTR_FORECAST_NATIVE_WIND_GUST_SPEED, ATTR_FORECAST_NATIVE_WIND_SPEED, - ATTR_FORECAST_PRECIPITATION, - ATTR_FORECAST_PRESSURE, - ATTR_FORECAST_TEMP, - ATTR_FORECAST_TEMP_LOW, ATTR_FORECAST_UV_INDEX, ATTR_FORECAST_WIND_BEARING, - ATTR_FORECAST_WIND_SPEED, Forecast, WeatherEntity, ) @@ -327,21 +322,3 @@ class MockWeatherMockLegacyForecastOnly(MockWeather): def forecast(self) -> list[Forecast] | None: """Return the forecast.""" return self.forecast_list - - -class MockWeatherMockForecastCompat(MockWeatherCompat): - """Mock weather class with mocked forecast for compatibility check.""" - - @property - def forecast(self) -> list[Forecast] | None: - """Return the forecast.""" - return [ - { - ATTR_FORECAST_TEMP: self.temperature, - ATTR_FORECAST_TEMP_LOW: self.temperature, - ATTR_FORECAST_PRESSURE: self.pressure, - ATTR_FORECAST_WIND_SPEED: self.wind_speed, - ATTR_FORECAST_WIND_BEARING: self.wind_bearing, - ATTR_FORECAST_PRECIPITATION: self._values.get("precipitation"), - } - ]