diff --git a/homeassistant/components/darksky/weather.py b/homeassistant/components/darksky/weather.py index 4965505150a56..e5ef3c827329a 100644 --- a/homeassistant/components/darksky/weather.py +++ b/homeassistant/components/darksky/weather.py @@ -36,8 +36,15 @@ CONF_LONGITUDE, CONF_MODE, CONF_NAME, + LENGTH_CENTIMETERS, + LENGTH_INCHES, + LENGTH_KILOMETERS, + LENGTH_MILES, PRESSURE_HPA, - PRESSURE_INHG, + PRESSURE_MBAR, + SPEED_KILOMETERS_PER_HOUR, + SPEED_METERS_PER_SECOND, + SPEED_MILES_PER_HOUR, TEMP_CELSIUS, TEMP_FAHRENHEIT, ) @@ -47,7 +54,6 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import Throttle from homeassistant.util.dt import utc_from_timestamp -from homeassistant.util.pressure import convert as convert_pressure _LOGGER = logging.getLogger(__name__) @@ -88,6 +94,35 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=3) +TEMPERATURE_UNIT = { + "si": TEMP_CELSIUS, + "us": TEMP_FAHRENHEIT, +} + +WIND_SPEED_UNIT = { + "ca": SPEED_KILOMETERS_PER_HOUR, + "si": SPEED_METERS_PER_SECOND, + "uk2": SPEED_MILES_PER_HOUR, + "us": SPEED_MILES_PER_HOUR, +} + +PRESSURE_UNIT = { + "si": PRESSURE_HPA, + "us": PRESSURE_MBAR, +} + +VISIBILITY_UNIT = { + "si": LENGTH_KILOMETERS, + "ca": LENGTH_KILOMETERS, + "uk2": LENGTH_MILES, + "us": LENGTH_MILES, +} + +PRECIPITATION_UNIT = { + "si": LENGTH_CENTIMETERS, + "us": LENGTH_INCHES, +} + def setup_platform( hass: HomeAssistant, @@ -145,10 +180,8 @@ def temperature(self): @property def temperature_unit(self): - """Return the unit of measurement.""" - if self._dark_sky.units is None: - return None - return TEMP_FAHRENHEIT if "us" in self._dark_sky.units else TEMP_CELSIUS + """Return the unit of measurement for temperature.""" + return TEMPERATURE_UNIT.get(self._dark_sky.units, TEMPERATURE_UNIT["si"]) @property def humidity(self): @@ -160,6 +193,11 @@ def wind_speed(self): """Return the wind speed.""" return self._ds_currently.get("windSpeed") + @property + def wind_speed_unit(self): + """Return the unit of measurement for wind speed.""" + return WIND_SPEED_UNIT.get(self._dark_sky.units, WIND_SPEED_UNIT["si"]) + @property def wind_bearing(self): """Return the wind bearing.""" @@ -173,21 +211,33 @@ def ozone(self): @property def pressure(self): """Return the pressure.""" - pressure = self._ds_currently.get("pressure") - if "us" in self._dark_sky.units: - return round(convert_pressure(pressure, PRESSURE_HPA, PRESSURE_INHG), 2) - return pressure + return self._ds_currently.get("pressure") + + @property + def pressure_unit(self): + """Return the unit of measurement for pressure.""" + return PRESSURE_UNIT.get(self._dark_sky.units, PRESSURE_UNIT["si"]) @property def visibility(self): """Return the visibility.""" return self._ds_currently.get("visibility") + @property + def visibility_unit(self): + """Return the unit of measurement for visibility.""" + return VISIBILITY_UNIT.get(self._dark_sky.units, VISIBILITY_UNIT["si"]) + @property def condition(self): """Return the weather condition.""" return MAP_CONDITION.get(self._ds_currently.get("icon")) + @property + def precipitation_unit(self): + """Return the unit of measurement for precipitation.""" + return PRECIPITATION_UNIT.get(self._dark_sky.units, PRECIPITATION_UNIT["si"]) + @property def forecast(self): """Return the forecast array.""" diff --git a/homeassistant/components/demo/weather.py b/homeassistant/components/demo/weather.py index 916083c5ad185..def067109e74b 100644 --- a/homeassistant/components/demo/weather.py +++ b/homeassistant/components/demo/weather.py @@ -27,7 +27,13 @@ WeatherEntity, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT +from homeassistant.const import ( + LENGTH_MILLIMETERS, + PRESSURE_HPA, + SPEED_KILOMETERS_PER_HOUR, + TEMP_CELSIUS, + TEMP_FAHRENHEIT, +) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType @@ -130,8 +136,11 @@ def __init__( self._temperature_unit = temperature_unit self._humidity = humidity self._pressure = pressure + self._pressure_unit = PRESSURE_HPA self._wind_speed = wind_speed + self._wind_speed_unit = SPEED_KILOMETERS_PER_HOUR self._forecast = forecast + self._precipitation_unit = LENGTH_MILLIMETERS @property def name(self): diff --git a/homeassistant/components/ecobee/weather.py b/homeassistant/components/ecobee/weather.py index 1c330ceb4e2f4..5a512bdb5980c 100644 --- a/homeassistant/components/ecobee/weather.py +++ b/homeassistant/components/ecobee/weather.py @@ -15,12 +15,16 @@ WeatherEntity, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import PRESSURE_HPA, PRESSURE_INHG, TEMP_FAHRENHEIT +from homeassistant.const import ( + LENGTH_METERS, + PRESSURE_HPA, + SPEED_MILES_PER_HOUR, + TEMP_FAHRENHEIT, +) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.util import dt as dt_util -from homeassistant.util.pressure import convert as pressure_convert from .const import ( DOMAIN, @@ -49,6 +53,11 @@ async def async_setup_entry( class EcobeeWeather(WeatherEntity): """Representation of Ecobee weather data.""" + _attr_temperature_unit = TEMP_FAHRENHEIT + _attr_wind_speed_unit = SPEED_MILES_PER_HOUR + _attr_visibility_unit = LENGTH_METERS + _attr_pressure_unit = PRESSURE_HPA + def __init__(self, data, name, index): """Initialize the Ecobee weather platform.""" self.data = data @@ -108,20 +117,11 @@ def temperature(self): except ValueError: return None - @property - def temperature_unit(self): - """Return the unit of measurement.""" - return TEMP_FAHRENHEIT - @property def pressure(self): """Return the pressure.""" try: - pressure = self.get_forecast(0, "pressure") - if not self.hass.config.units.is_metric: - pressure = pressure_convert(pressure, PRESSURE_HPA, PRESSURE_INHG) - return round(pressure, 2) - return round(pressure) + return int(self.get_forecast(0, "pressure")) except ValueError: return None diff --git a/homeassistant/components/environment_canada/weather.py b/homeassistant/components/environment_canada/weather.py index 06bdd0dffc7be..a74d973b06b3a 100644 --- a/homeassistant/components/environment_canada/weather.py +++ b/homeassistant/components/environment_canada/weather.py @@ -27,7 +27,13 @@ WeatherEntity, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import TEMP_CELSIUS +from homeassistant.const import ( + LENGTH_KILOMETERS, + LENGTH_MILLIMETERS, + PRESSURE_KPA, + SPEED_KILOMETERS_PER_HOUR, + TEMP_CELSIUS, +) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -76,6 +82,12 @@ async def async_setup_entry( class ECWeather(CoordinatorEntity, WeatherEntity): """Representation of a weather condition.""" + _attr_temperature_unit = TEMP_CELSIUS + _attr_wind_speed_unit = SPEED_KILOMETERS_PER_HOUR + _attr_pressure_unit = PRESSURE_KPA + _attr_visibility_unit = LENGTH_KILOMETERS + _attr_precipitation_unit = LENGTH_MILLIMETERS + def __init__(self, coordinator, hourly): """Initialize Environment Canada weather.""" super().__init__(coordinator) @@ -101,11 +113,6 @@ def temperature(self): return float(self.ec_data.hourly_forecasts[0]["temperature"]) return None - @property - def temperature_unit(self): - """Return the unit of measurement.""" - return TEMP_CELSIUS - @property def humidity(self): """Return the humidity.""" @@ -131,7 +138,7 @@ def wind_bearing(self): def pressure(self): """Return the pressure.""" if self.ec_data.conditions.get("pressure", {}).get("value"): - return 10 * float(self.ec_data.conditions["pressure"]["value"]) + return float(self.ec_data.conditions["pressure"]["value"]) return None @property diff --git a/homeassistant/components/homematicip_cloud/weather.py b/homeassistant/components/homematicip_cloud/weather.py index 985754a8417d9..4c4b5f97bdf34 100644 --- a/homeassistant/components/homematicip_cloud/weather.py +++ b/homeassistant/components/homematicip_cloud/weather.py @@ -22,7 +22,7 @@ WeatherEntity, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import TEMP_CELSIUS +from homeassistant.const import SPEED_KILOMETERS_PER_HOUR, TEMP_CELSIUS from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -71,6 +71,9 @@ async def async_setup_entry( class HomematicipWeatherSensor(HomematicipGenericEntity, WeatherEntity): """Representation of the HomematicIP weather sensor plus & basic.""" + _attr_temperature_unit = TEMP_CELSIUS + _attr_wind_speed_unit = SPEED_KILOMETERS_PER_HOUR + def __init__(self, hap: HomematicipHAP, device) -> None: """Initialize the weather sensor.""" super().__init__(hap, device) @@ -85,11 +88,6 @@ def temperature(self) -> float: """Return the platform temperature.""" return self._device.actualTemperature - @property - def temperature_unit(self) -> str: - """Return the unit of measurement.""" - return TEMP_CELSIUS - @property def humidity(self) -> int: """Return the humidity.""" @@ -129,6 +127,9 @@ def wind_bearing(self) -> float: class HomematicipHomeWeather(HomematicipGenericEntity, WeatherEntity): """Representation of the HomematicIP home weather.""" + _attr_temperature_unit = TEMP_CELSIUS + _attr_wind_speed_unit = SPEED_KILOMETERS_PER_HOUR + def __init__(self, hap: HomematicipHAP) -> None: """Initialize the home weather.""" hap.home.modelType = "HmIP-Home-Weather" @@ -149,11 +150,6 @@ def temperature(self) -> float: """Return the temperature.""" return self._device.weather.temperature - @property - def temperature_unit(self) -> str: - """Return the unit of measurement.""" - return TEMP_CELSIUS - @property def humidity(self) -> int: """Return the humidity.""" diff --git a/homeassistant/components/ipma/weather.py b/homeassistant/components/ipma/weather.py index 731c3d7fb60e6..603a71a1ae318 100644 --- a/homeassistant/components/ipma/weather.py +++ b/homeassistant/components/ipma/weather.py @@ -40,6 +40,7 @@ CONF_LONGITUDE, CONF_MODE, CONF_NAME, + SPEED_KILOMETERS_PER_HOUR, TEMP_CELSIUS, ) from homeassistant.core import HomeAssistant, callback @@ -174,6 +175,9 @@ async def async_get_location(hass, api, latitude, longitude): class IPMAWeather(WeatherEntity): """Representation of a weather condition.""" + _attr_temperature_unit = TEMP_CELSIUS + _attr_wind_speed_unit = SPEED_KILOMETERS_PER_HOUR + def __init__(self, location: Location, api: IPMA_API, config): """Initialise the platform with a data instance and station name.""" self._api = api @@ -276,11 +280,6 @@ def wind_bearing(self): return self._observation.wind_direction - @property - def temperature_unit(self): - """Return the unit of measurement.""" - return TEMP_CELSIUS - @property def forecast(self): """Return the forecast array.""" @@ -313,7 +312,7 @@ def forecast(self): if int(float(data_in.precipitation_probability)) >= 0 else None ), - ATTR_FORECAST_WIND_SPEED: data_in.wind_strength, + ATTR_FORECAST_WIND_SPEED: float(data_in.wind_strength), ATTR_FORECAST_WIND_BEARING: data_in.wind_direction, } for data_in in forecast_filtered @@ -334,7 +333,7 @@ def forecast(self): ATTR_FORECAST_TEMP_LOW: data_in.min_temperature, ATTR_FORECAST_TEMP: data_in.max_temperature, ATTR_FORECAST_PRECIPITATION_PROBABILITY: data_in.precipitation_probability, - ATTR_FORECAST_WIND_SPEED: data_in.wind_strength, + ATTR_FORECAST_WIND_SPEED: float(data_in.wind_strength), ATTR_FORECAST_WIND_BEARING: data_in.wind_direction, } for data_in in forecast_filtered diff --git a/tests/components/homematicip_cloud/test_weather.py b/tests/components/homematicip_cloud/test_weather.py index 4861a4d269698..0b35036a8c0fd 100644 --- a/tests/components/homematicip_cloud/test_weather.py +++ b/tests/components/homematicip_cloud/test_weather.py @@ -37,7 +37,7 @@ async def test_hmip_weather_sensor(hass, default_mock_hap_factory): assert ha_state.state == "" assert ha_state.attributes[ATTR_WEATHER_TEMPERATURE] == 4.3 assert ha_state.attributes[ATTR_WEATHER_HUMIDITY] == 97 - assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 15.0 + assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 4.17 assert ha_state.attributes[ATTR_ATTRIBUTION] == "Powered by Homematic IP" await async_manipulate_test_data(hass, hmip_device, "actualTemperature", 12.1) @@ -61,7 +61,7 @@ async def test_hmip_weather_sensor_pro(hass, default_mock_hap_factory): assert ha_state.state == "sunny" assert ha_state.attributes[ATTR_WEATHER_TEMPERATURE] == 15.4 assert ha_state.attributes[ATTR_WEATHER_HUMIDITY] == 65 - assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 2.6 + assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 0.72 assert ha_state.attributes[ATTR_WEATHER_WIND_BEARING] == 295.0 assert ha_state.attributes[ATTR_ATTRIBUTION] == "Powered by Homematic IP" @@ -84,7 +84,7 @@ async def test_hmip_home_weather(hass, default_mock_hap_factory): assert ha_state.state == "partlycloudy" assert ha_state.attributes[ATTR_WEATHER_TEMPERATURE] == 16.6 assert ha_state.attributes[ATTR_WEATHER_HUMIDITY] == 54 - assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 8.6 + assert ha_state.attributes[ATTR_WEATHER_WIND_SPEED] == 2.39 assert ha_state.attributes[ATTR_WEATHER_WIND_BEARING] == 294 assert ha_state.attributes[ATTR_ATTRIBUTION] == "Powered by Homematic IP" diff --git a/tests/components/ipma/test_weather.py b/tests/components/ipma/test_weather.py index 7ed1c4d3723da..739561d851d60 100644 --- a/tests/components/ipma/test_weather.py +++ b/tests/components/ipma/test_weather.py @@ -19,6 +19,7 @@ ATTR_WEATHER_WIND_SPEED, DOMAIN as WEATHER_DOMAIN, ) +from homeassistant.const import SPEED_KILOMETERS_PER_HOUR from homeassistant.setup import async_setup_component from homeassistant.util.dt import now @@ -131,6 +132,7 @@ def station_longitude(self): async def test_setup_configuration(hass): """Test for successfully setting up the IPMA platform.""" + hass.config.units.wind_speed_unit = SPEED_KILOMETERS_PER_HOUR with patch( "homeassistant.components.ipma.weather.async_get_location", return_value=MockLocation(), @@ -198,7 +200,7 @@ async def test_daily_forecast(hass): assert forecast.get(ATTR_FORECAST_TEMP) == 16.2 assert forecast.get(ATTR_FORECAST_TEMP_LOW) == 10.6 assert forecast.get(ATTR_FORECAST_PRECIPITATION_PROBABILITY) == "100.0" - assert forecast.get(ATTR_FORECAST_WIND_SPEED) == "10" + assert forecast.get(ATTR_FORECAST_WIND_SPEED) == 10 assert forecast.get(ATTR_FORECAST_WIND_BEARING) == "S" @@ -222,5 +224,5 @@ async def test_hourly_forecast(hass): assert forecast.get(ATTR_FORECAST_CONDITION) == "rainy" assert forecast.get(ATTR_FORECAST_TEMP) == 7.7 assert forecast.get(ATTR_FORECAST_PRECIPITATION_PROBABILITY) == 80.0 - assert forecast.get(ATTR_FORECAST_WIND_SPEED) == "32.7" + assert forecast.get(ATTR_FORECAST_WIND_SPEED) == 32.7 assert forecast.get(ATTR_FORECAST_WIND_BEARING) == "S"