diff --git a/homeassistant/components/nws/const.py b/homeassistant/components/nws/const.py index 707186abebf..7a07c1cf7c0 100644 --- a/homeassistant/components/nws/const.py +++ b/homeassistant/components/nws/const.py @@ -1,14 +1,8 @@ """Constants for National Weather Service Integration.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta -from homeassistant.components.sensor import ( - SensorDeviceClass, - SensorEntityDescription, - SensorStateClass, -) from homeassistant.components.weather import ( ATTR_CONDITION_CLOUDY, ATTR_CONDITION_EXCEPTIONAL, @@ -24,17 +18,6 @@ from homeassistant.components.weather import ( ATTR_CONDITION_WINDY, ATTR_CONDITION_WINDY_VARIANT, ) -from homeassistant.const import ( - DEGREE, - LENGTH_METERS, - LENGTH_MILES, - PERCENTAGE, - PRESSURE_INHG, - PRESSURE_PA, - SPEED_KILOMETERS_PER_HOUR, - SPEED_MILES_PER_HOUR, - TEMP_CELSIUS, -) DOMAIN = "nws" @@ -99,113 +82,3 @@ COORDINATOR_FORECAST_HOURLY = "coordinator_forecast_hourly" OBSERVATION_VALID_TIME = timedelta(minutes=20) FORECAST_VALID_TIME = timedelta(minutes=45) - - -@dataclass -class NWSSensorEntityDescription(SensorEntityDescription): - """Class describing NWSSensor entities.""" - - unit_convert: str | None = None - - -SENSOR_TYPES: tuple[NWSSensorEntityDescription, ...] = ( - NWSSensorEntityDescription( - key="dewpoint", - name="Dew Point", - icon=None, - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=TEMP_CELSIUS, - unit_convert=TEMP_CELSIUS, - ), - NWSSensorEntityDescription( - key="temperature", - name="Temperature", - icon=None, - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=TEMP_CELSIUS, - unit_convert=TEMP_CELSIUS, - ), - NWSSensorEntityDescription( - key="windChill", - name="Wind Chill", - icon=None, - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=TEMP_CELSIUS, - unit_convert=TEMP_CELSIUS, - ), - NWSSensorEntityDescription( - key="heatIndex", - name="Heat Index", - icon=None, - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=TEMP_CELSIUS, - unit_convert=TEMP_CELSIUS, - ), - NWSSensorEntityDescription( - key="relativeHumidity", - name="Relative Humidity", - icon=None, - device_class=SensorDeviceClass.HUMIDITY, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=PERCENTAGE, - unit_convert=PERCENTAGE, - ), - NWSSensorEntityDescription( - key="windSpeed", - name="Wind Speed", - icon="mdi:weather-windy", - device_class=None, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=SPEED_KILOMETERS_PER_HOUR, - unit_convert=SPEED_MILES_PER_HOUR, - ), - NWSSensorEntityDescription( - key="windGust", - name="Wind Gust", - icon="mdi:weather-windy", - device_class=None, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=SPEED_KILOMETERS_PER_HOUR, - unit_convert=SPEED_MILES_PER_HOUR, - ), - NWSSensorEntityDescription( - key="windDirection", - name="Wind Direction", - icon="mdi:compass-rose", - device_class=None, - state_class=None, # statistics currently doesn't handle circular statistics - native_unit_of_measurement=DEGREE, - unit_convert=DEGREE, - ), - NWSSensorEntityDescription( - key="barometricPressure", - name="Barometric Pressure", - icon=None, - device_class=SensorDeviceClass.PRESSURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=PRESSURE_PA, - unit_convert=PRESSURE_INHG, - ), - NWSSensorEntityDescription( - key="seaLevelPressure", - name="Sea Level Pressure", - icon=None, - device_class=SensorDeviceClass.PRESSURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=PRESSURE_PA, - unit_convert=PRESSURE_INHG, - ), - NWSSensorEntityDescription( - key="visibility", - name="Visibility", - icon="mdi:eye", - device_class=None, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=LENGTH_METERS, - unit_convert=LENGTH_MILES, - ), -) diff --git a/homeassistant/components/nws/sensor.py b/homeassistant/components/nws/sensor.py index 2e7495701a9..983eb9f79d4 100644 --- a/homeassistant/components/nws/sensor.py +++ b/homeassistant/components/nws/sensor.py @@ -1,17 +1,24 @@ """Sensors for National Weather Service (NWS).""" -from homeassistant.components.sensor import SensorEntity +from __future__ import annotations + +from dataclasses import dataclass + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, + SensorStateClass, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_LATITUDE, CONF_LONGITUDE, - LENGTH_METERS, - LENGTH_MILES, + DEGREE, PERCENTAGE, - PRESSURE_INHG, - PRESSURE_PA, - SPEED_KILOMETERS_PER_HOUR, - SPEED_MILES_PER_HOUR, - TEMP_CELSIUS, + UnitOfLength, + UnitOfPressure, + UnitOfSpeed, + UnitOfTemperature, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo @@ -33,13 +40,110 @@ from .const import ( DOMAIN, NWS_DATA, OBSERVATION_VALID_TIME, - SENSOR_TYPES, - NWSSensorEntityDescription, ) PARALLEL_UPDATES = 0 +@dataclass +class NWSSensorEntityDescription(SensorEntityDescription): + """Class describing NWSSensor entities.""" + + unit_convert: str | None = None + + +SENSOR_TYPES: tuple[NWSSensorEntityDescription, ...] = ( + NWSSensorEntityDescription( + key="dewpoint", + name="Dew Point", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + unit_convert=UnitOfTemperature.CELSIUS, + ), + NWSSensorEntityDescription( + key="temperature", + name="Temperature", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + unit_convert=UnitOfTemperature.CELSIUS, + ), + NWSSensorEntityDescription( + key="windChill", + name="Wind Chill", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + unit_convert=UnitOfTemperature.CELSIUS, + ), + NWSSensorEntityDescription( + key="heatIndex", + name="Heat Index", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + unit_convert=UnitOfTemperature.CELSIUS, + ), + NWSSensorEntityDescription( + key="relativeHumidity", + name="Relative Humidity", + device_class=SensorDeviceClass.HUMIDITY, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + unit_convert=PERCENTAGE, + ), + NWSSensorEntityDescription( + key="windSpeed", + name="Wind Speed", + device_class=SensorDeviceClass.WIND_SPEED, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR, + unit_convert=UnitOfSpeed.MILES_PER_HOUR, + ), + NWSSensorEntityDescription( + key="windGust", + name="Wind Gust", + device_class=SensorDeviceClass.WIND_SPEED, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR, + unit_convert=UnitOfSpeed.MILES_PER_HOUR, + ), + # statistics currently doesn't handle circular statistics + NWSSensorEntityDescription( + key="windDirection", + name="Wind Direction", + icon="mdi:compass-rose", + native_unit_of_measurement=DEGREE, + unit_convert=DEGREE, + ), + NWSSensorEntityDescription( + key="barometricPressure", + name="Barometric Pressure", + device_class=SensorDeviceClass.PRESSURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPressure.PA, + unit_convert=UnitOfPressure.INHG, + ), + NWSSensorEntityDescription( + key="seaLevelPressure", + name="Sea Level Pressure", + device_class=SensorDeviceClass.PRESSURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPressure.PA, + unit_convert=UnitOfPressure.INHG, + ), + NWSSensorEntityDescription( + key="visibility", + name="Visibility", + icon="mdi:eye", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfLength.METERS, + unit_convert=UnitOfLength.MILES, + ), +) + + async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: @@ -92,19 +196,26 @@ class NWSSensor(CoordinatorEntity, SensorEntity): return None # Set alias to unit property -> prevent unnecessary hasattr calls unit_of_measurement = self.native_unit_of_measurement - if unit_of_measurement == SPEED_MILES_PER_HOUR: + if unit_of_measurement == UnitOfSpeed.MILES_PER_HOUR: return round( SpeedConverter.convert( - value, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR + value, UnitOfSpeed.KILOMETERS_PER_HOUR, UnitOfSpeed.MILES_PER_HOUR ) ) - if unit_of_measurement == LENGTH_MILES: - return round(DistanceConverter.convert(value, LENGTH_METERS, LENGTH_MILES)) - if unit_of_measurement == PRESSURE_INHG: + if unit_of_measurement == UnitOfLength.MILES: return round( - PressureConverter.convert(value, PRESSURE_PA, PRESSURE_INHG), 2 + DistanceConverter.convert( + value, UnitOfLength.METERS, UnitOfLength.MILES + ) ) - if unit_of_measurement == TEMP_CELSIUS: + if unit_of_measurement == UnitOfPressure.INHG: + return round( + PressureConverter.convert( + value, UnitOfPressure.PA, UnitOfPressure.INHG + ), + 2, + ) + if unit_of_measurement == UnitOfTemperature.CELSIUS: return round(value, 1) if unit_of_measurement == PERCENTAGE: return round(value) diff --git a/tests/components/nws/test_sensor.py b/tests/components/nws/test_sensor.py index 9597618ccc8..a42dba542d1 100644 --- a/tests/components/nws/test_sensor.py +++ b/tests/components/nws/test_sensor.py @@ -1,7 +1,8 @@ """Sensors for National Weather Service (NWS).""" import pytest -from homeassistant.components.nws.const import ATTRIBUTION, DOMAIN, SENSOR_TYPES +from homeassistant.components.nws.const import ATTRIBUTION, DOMAIN +from homeassistant.components.nws.sensor import SENSOR_TYPES from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.const import ATTR_ATTRIBUTION, STATE_UNKNOWN from homeassistant.helpers import entity_registry as er