Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions homeassistant/components/climacell/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
UnknownException,
)

from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
Expand All @@ -34,6 +35,7 @@
)

from .const import (
ATTR_FIELD,
ATTRIBUTION,
CC_ATTR_CLOUD_COVER,
CC_ATTR_CONDITION,
Expand All @@ -50,6 +52,7 @@
CC_ATTR_WIND_DIRECTION,
CC_ATTR_WIND_GUST,
CC_ATTR_WIND_SPEED,
CC_SENSOR_TYPES,
CC_V3_ATTR_CLOUD_COVER,
CC_V3_ATTR_CONDITION,
CC_V3_ATTR_HUMIDITY,
Expand All @@ -64,16 +67,16 @@
CC_V3_ATTR_WIND_DIRECTION,
CC_V3_ATTR_WIND_GUST,
CC_V3_ATTR_WIND_SPEED,
CC_V3_SENSOR_TYPES,
CONF_TIMESTEP,
DEFAULT_FORECAST_TYPE,
DEFAULT_TIMESTEP,
DOMAIN,
MAX_REQUESTS_PER_DAY,
)

_LOGGER = logging.getLogger(__name__)

PLATFORMS = [WEATHER_DOMAIN]
PLATFORMS = [SENSOR_DOMAIN, WEATHER_DOMAIN]


def _set_update_interval(
Expand Down Expand Up @@ -232,6 +235,10 @@ async def _async_update_data(self) -> dict[str, Any]:
CC_V3_ATTR_WIND_GUST,
CC_V3_ATTR_CLOUD_COVER,
CC_V3_ATTR_PRECIPITATION_TYPE,
*[
sensor_type[ATTR_FIELD]
for sensor_type in CC_V3_SENSOR_TYPES
],
]
)
data[FORECASTS][HOURLY] = await self._api.forecast_hourly(
Expand Down Expand Up @@ -288,6 +295,7 @@ async def _async_update_data(self) -> dict[str, Any]:
CC_ATTR_WIND_GUST,
CC_ATTR_CLOUD_COVER,
CC_ATTR_PRECIPITATION_TYPE,
*[sensor_type[ATTR_FIELD] for sensor_type in CC_SENSOR_TYPES],
],
[
CC_ATTR_TEMPERATURE_LOW,
Expand Down Expand Up @@ -317,20 +325,22 @@ def __init__(
self,
config_entry: ConfigEntry,
coordinator: ClimaCellDataUpdateCoordinator,
forecast_type: str,
api_version: int,
) -> None:
"""Initialize ClimaCell Entity."""
super().__init__(coordinator)
self.api_version = api_version
self.forecast_type = forecast_type
self._config_entry = config_entry

@staticmethod
def _get_cc_value(
weather_dict: dict[str, Any], key: str
) -> int | float | str | None:
"""Return property from weather_dict."""
"""
Return property from weather_dict.

Used for V3 API.
"""
items = weather_dict.get(key, {})
# Handle cases where value returned is a list.
# Optimistically find the best value to return.
Expand All @@ -347,23 +357,13 @@ def _get_cc_value(

return items.get("value")

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
if self.forecast_type == DEFAULT_FORECAST_TYPE:
return True

return False
def _get_current_property(self, property_name: str) -> int | str | float | None:
"""
Get property from current conditions.

@property
def name(self) -> str:
"""Return the name of the entity."""
return f"{self._config_entry.data[CONF_NAME]} - {self.forecast_type.title()}"

@property
def unique_id(self) -> str:
"""Return the unique id of the entity."""
return f"{self._config_entry.unique_id}_{self.forecast_type}"
Used for V4 API.
"""
return self.coordinator.data.get(CURRENT, {}).get(property_name)

@property
def attribution(self):
Expand All @@ -377,6 +377,6 @@ def device_info(self) -> dict[str, Any]:
"identifiers": {(DOMAIN, self._config_entry.data[CONF_API_KEY])},
"name": "ClimaCell",
"manufacturer": "ClimaCell",
"sw_version": "v3",
"sw_version": f"v{self.api_version}",
"entry_type": "service",
}
186 changes: 185 additions & 1 deletion homeassistant/components/climacell/const.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
"""Constants for the ClimaCell integration."""
from pyclimacell.const import DAILY, HOURLY, NOWCAST, WeatherCode
from pyclimacell.const import (
DAILY,
HOURLY,
NOWCAST,
HealthConcernType,
PollenIndex,
PrimaryPollutantType,
WeatherCode,
)

from homeassistant.components.weather import (
ATTR_CONDITION_CLEAR_NIGHT,
Expand All @@ -15,6 +23,15 @@
ATTR_CONDITION_SUNNY,
ATTR_CONDITION_WINDY,
)
from homeassistant.const import (
ATTR_NAME,
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
CONF_UNIT_OF_MEASUREMENT,
CONF_UNIT_SYSTEM_IMPERIAL,
CONF_UNIT_SYSTEM_METRIC,
)

CONF_TIMESTEP = "timestep"
FORECAST_TYPES = [DAILY, HOURLY, NOWCAST]
Expand All @@ -35,6 +52,12 @@
NOWCAST: 30,
}

# Sensor type keys
ATTR_FIELD = "field"
ATTR_METRIC_CONVERSION = "metric_conversion"
ATTR_VALUE_MAP = "value_map"
ATTR_IS_METRIC_CHECK = "is_metric_check"

# Additional attributes
ATTR_WIND_GUST = "wind_gust"
ATTR_CLOUD_COVER = "cloud_cover"
Expand Down Expand Up @@ -68,6 +91,7 @@
WeatherCode.PARTLY_CLOUDY: ATTR_CONDITION_PARTLYCLOUDY,
}

# Weather constants
CC_ATTR_TIMESTAMP = "startTime"
CC_ATTR_TEMPERATURE = "temperature"
CC_ATTR_TEMPERATURE_HIGH = "temperatureMax"
Expand All @@ -85,6 +109,95 @@
CC_ATTR_CLOUD_COVER = "cloudCover"
CC_ATTR_PRECIPITATION_TYPE = "precipitationType"

# Sensor attributes
CC_ATTR_PARTICULATE_MATTER_25 = "particulateMatter25"
CC_ATTR_PARTICULATE_MATTER_10 = "particulateMatter10"
CC_ATTR_NITROGEN_DIOXIDE = "pollutantNO2"
CC_ATTR_CARBON_MONOXIDE = "pollutantCO"
CC_ATTR_SULFUR_DIOXIDE = "pollutantSO2"
CC_ATTR_EPA_AQI = "epaIndex"
CC_ATTR_EPA_PRIMARY_POLLUTANT = "epaPrimaryPollutant"
CC_ATTR_EPA_HEALTH_CONCERN = "epaHealthConcern"
CC_ATTR_CHINA_AQI = "mepIndex"
CC_ATTR_CHINA_PRIMARY_POLLUTANT = "mepPrimaryPollutant"
CC_ATTR_CHINA_HEALTH_CONCERN = "mepHealthConcern"
CC_ATTR_POLLEN_TREE = "treeIndex"
CC_ATTR_POLLEN_WEED = "weedIndex"
CC_ATTR_POLLEN_GRASS = "grassIndex"
CC_ATTR_FIRE_INDEX = "fireIndex"

CC_SENSOR_TYPES = [
{
ATTR_FIELD: CC_ATTR_PARTICULATE_MATTER_25,
ATTR_NAME: "Particulate Matter < 2.5 μm",
CONF_UNIT_SYSTEM_IMPERIAL: "μg/ft³",
CONF_UNIT_SYSTEM_METRIC: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_METRIC_CONVERSION: 3.2808399 ** 3,
ATTR_IS_METRIC_CHECK: True,
},
{
ATTR_FIELD: CC_ATTR_PARTICULATE_MATTER_10,
ATTR_NAME: "Particulate Matter < 10 μm",
CONF_UNIT_SYSTEM_IMPERIAL: "μg/ft³",
CONF_UNIT_SYSTEM_METRIC: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_METRIC_CONVERSION: 3.2808399 ** 3,
ATTR_IS_METRIC_CHECK: True,
},
{
ATTR_FIELD: CC_ATTR_NITROGEN_DIOXIDE,
ATTR_NAME: "Nitrogen Dioxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_BILLION,
},
{
ATTR_FIELD: CC_ATTR_CARBON_MONOXIDE,
ATTR_NAME: "Carbon Monoxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_BILLION,
},
{
ATTR_FIELD: CC_ATTR_SULFUR_DIOXIDE,
ATTR_NAME: "Sulfur Dioxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_BILLION,
},
{ATTR_FIELD: CC_ATTR_EPA_AQI, ATTR_NAME: "US EPA Air Quality Index"},
{
ATTR_FIELD: CC_ATTR_EPA_PRIMARY_POLLUTANT,
ATTR_NAME: "US EPA Primary Pollutant",
ATTR_VALUE_MAP: PrimaryPollutantType,
},
{
ATTR_FIELD: CC_ATTR_EPA_HEALTH_CONCERN,
ATTR_NAME: "US EPA Health Concern",
ATTR_VALUE_MAP: HealthConcernType,
},
{ATTR_FIELD: CC_ATTR_CHINA_AQI, ATTR_NAME: "China MEP Air Quality Index"},
{
ATTR_FIELD: CC_ATTR_CHINA_PRIMARY_POLLUTANT,
ATTR_NAME: "China MEP Primary Pollutant",
ATTR_VALUE_MAP: PrimaryPollutantType,
},
{
ATTR_FIELD: CC_ATTR_CHINA_HEALTH_CONCERN,
ATTR_NAME: "China MEP Health Concern",
ATTR_VALUE_MAP: HealthConcernType,
},
{
ATTR_FIELD: CC_ATTR_POLLEN_TREE,
ATTR_NAME: "Tree Pollen Index",
ATTR_VALUE_MAP: PollenIndex,
},
{
ATTR_FIELD: CC_ATTR_POLLEN_WEED,
ATTR_NAME: "Weed Pollen Index",
ATTR_VALUE_MAP: PollenIndex,
},
{
ATTR_FIELD: CC_ATTR_POLLEN_GRASS,
ATTR_NAME: "Grass Pollen Index",
ATTR_VALUE_MAP: PollenIndex,
},
{ATTR_FIELD: CC_ATTR_FIRE_INDEX, ATTR_NAME: "Fire Index"},
]

# V3 constants
CONDITIONS_V3 = {
"breezy": ATTR_CONDITION_WINDY,
Expand All @@ -111,6 +224,7 @@
"partly_cloudy": ATTR_CONDITION_PARTLYCLOUDY,
}

# Weather attributes
CC_V3_ATTR_TIMESTAMP = "observation_time"
CC_V3_ATTR_TEMPERATURE = "temp"
CC_V3_ATTR_TEMPERATURE_HIGH = "max"
Expand All @@ -128,3 +242,73 @@
CC_V3_ATTR_WIND_GUST = "wind_gust"
CC_V3_ATTR_CLOUD_COVER = "cloud_cover"
CC_V3_ATTR_PRECIPITATION_TYPE = "precipitation_type"

# Sensor attributes
CC_V3_ATTR_PARTICULATE_MATTER_25 = "pm25"
CC_V3_ATTR_PARTICULATE_MATTER_10 = "pm10"
CC_V3_ATTR_NITROGEN_DIOXIDE = "no2"
CC_V3_ATTR_CARBON_MONOXIDE = "co"
CC_V3_ATTR_SULFUR_DIOXIDE = "so2"
CC_V3_ATTR_EPA_AQI = "epa_aqi"
CC_V3_ATTR_EPA_PRIMARY_POLLUTANT = "epa_primary_pollutant"
CC_V3_ATTR_EPA_HEALTH_CONCERN = "epa_health_concern"
CC_V3_ATTR_CHINA_AQI = "china_aqi"
CC_V3_ATTR_CHINA_PRIMARY_POLLUTANT = "china_primary_pollutant"
CC_V3_ATTR_CHINA_HEALTH_CONCERN = "china_health_concern"
CC_V3_ATTR_POLLEN_TREE = "pollen_tree"
CC_V3_ATTR_POLLEN_WEED = "pollen_weed"
CC_V3_ATTR_POLLEN_GRASS = "pollen_grass"
CC_V3_ATTR_FIRE_INDEX = "fire_index"

CC_V3_SENSOR_TYPES = [
{
ATTR_FIELD: CC_V3_ATTR_PARTICULATE_MATTER_25,
ATTR_NAME: "Particulate Matter < 2.5 μm",
CONF_UNIT_SYSTEM_IMPERIAL: "μg/ft³",
CONF_UNIT_SYSTEM_METRIC: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_METRIC_CONVERSION: 1 / (3.2808399 ** 3),
ATTR_IS_METRIC_CHECK: False,
},
{
ATTR_FIELD: CC_V3_ATTR_PARTICULATE_MATTER_10,
ATTR_NAME: "Particulate Matter < 10 μm",
CONF_UNIT_SYSTEM_IMPERIAL: "μg/ft³",
CONF_UNIT_SYSTEM_METRIC: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ATTR_METRIC_CONVERSION: 1 / (3.2808399 ** 3),
ATTR_IS_METRIC_CHECK: False,
},
{
ATTR_FIELD: CC_V3_ATTR_NITROGEN_DIOXIDE,
ATTR_NAME: "Nitrogen Dioxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_BILLION,
},
{
ATTR_FIELD: CC_V3_ATTR_CARBON_MONOXIDE,
ATTR_NAME: "Carbon Monoxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_MILLION,
},
{
ATTR_FIELD: CC_V3_ATTR_SULFUR_DIOXIDE,
ATTR_NAME: "Sulfur Dioxide",
CONF_UNIT_OF_MEASUREMENT: CONCENTRATION_PARTS_PER_BILLION,
},
{ATTR_FIELD: CC_V3_ATTR_EPA_AQI, ATTR_NAME: "US EPA Air Quality Index"},
{
ATTR_FIELD: CC_V3_ATTR_EPA_PRIMARY_POLLUTANT,
ATTR_NAME: "US EPA Primary Pollutant",
},
{ATTR_FIELD: CC_V3_ATTR_EPA_HEALTH_CONCERN, ATTR_NAME: "US EPA Health Concern"},
{ATTR_FIELD: CC_V3_ATTR_CHINA_AQI, ATTR_NAME: "China MEP Air Quality Index"},
{
ATTR_FIELD: CC_V3_ATTR_CHINA_PRIMARY_POLLUTANT,
ATTR_NAME: "China MEP Primary Pollutant",
},
{
ATTR_FIELD: CC_V3_ATTR_CHINA_HEALTH_CONCERN,
ATTR_NAME: "China MEP Health Concern",
},
{ATTR_FIELD: CC_V3_ATTR_POLLEN_TREE, ATTR_NAME: "Tree Pollen Index"},
{ATTR_FIELD: CC_V3_ATTR_POLLEN_WEED, ATTR_NAME: "Weed Pollen Index"},
{ATTR_FIELD: CC_V3_ATTR_POLLEN_GRASS, ATTR_NAME: "Grass Pollen Index"},
{ATTR_FIELD: CC_V3_ATTR_FIRE_INDEX, ATTR_NAME: "Fire Index"},
]
Loading