Skip to content

Commit

Permalink
2024.6.1 (#119096)
Browse files Browse the repository at this point in the history
  • Loading branch information
frenck authored Jun 7, 2024
2 parents 460909a + 3f70e2b commit b28cdcf
Show file tree
Hide file tree
Showing 60 changed files with 777 additions and 329 deletions.
13 changes: 10 additions & 3 deletions homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,15 @@


DEBUGGER_INTEGRATIONS = {"debugpy"}

# Core integrations are unconditionally loaded
CORE_INTEGRATIONS = {"homeassistant", "persistent_notification"}
LOGGING_INTEGRATIONS = {

# Integrations that are loaded right after the core is set up
LOGGING_AND_HTTP_DEPS_INTEGRATIONS = {
# isal is loaded right away before `http` to ensure if its
# enabled, that `isal` is up to date.
"isal",
# Set log levels
"logger",
# Error logging
Expand Down Expand Up @@ -214,8 +221,8 @@
}

SETUP_ORDER = (
# Load logging as soon as possible
("logging", LOGGING_INTEGRATIONS),
# Load logging and http deps as soon as possible
("logging, http deps", LOGGING_AND_HTTP_DEPS_INTEGRATIONS),
# Setup frontend and recorder
("frontend, recorder", {*FRONTEND_INTEGRATIONS, *RECORDER_INTEGRATIONS}),
# Start up debuggers. Start these first in case they want to wait.
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/agent_dvr/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class AgentBaseStation(AlarmControlPanelEntity):
| AlarmControlPanelEntityFeature.ARM_AWAY
| AlarmControlPanelEntityFeature.ARM_NIGHT
)
_attr_code_arm_required = False
_attr_has_entity_name = True
_attr_name = None

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/airgradient/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"domain": "airgradient",
"name": "Airgradient",
"name": "AirGradient",
"codeowners": ["@airgradienthq", "@joostlek"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airgradient",
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/airgradient/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class AirGradientSensorEntityDescription(SensorEntityDescription):
AirGradientSensorEntityDescription(
key="pm003",
translation_key="pm003_count",
native_unit_of_measurement="particles/dL",
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda status: status.pm003_count,
),
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/airgradient/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"name": "Nitrogen index"
},
"pm003_count": {
"name": "PM0.3 count"
"name": "PM0.3"
},
"raw_total_volatile_organic_component": {
"name": "Raw total VOC"
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/azure_data_explorer/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
"title": "Setup your Azure Data Explorer integration",
"description": "Enter connection details.",
"data": {
"clusteringesturi": "Cluster Ingest URI",
"cluster_ingest_uri": "Cluster ingest URI",
"database": "Database name",
"table": "Table name",
"client_id": "Client ID",
"client_secret": "Client secret",
"authority_id": "Authority ID"
"authority_id": "Authority ID",
"use_queued_ingestion": "Use queued ingestion"
}
}
},
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/blink/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class BlinkSyncModuleHA(
"""Representation of a Blink Alarm Control Panel."""

_attr_supported_features = AlarmControlPanelEntityFeature.ARM_AWAY
_attr_code_arm_required = False
_attr_has_entity_name = True
_attr_name = None

Expand Down
90 changes: 21 additions & 69 deletions homeassistant/components/climate/intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

import voluptuous as vol

from homeassistant.core import HomeAssistant, State
from homeassistant.core import HomeAssistant
from homeassistant.helpers import intent
from homeassistant.helpers.entity_component import EntityComponent

from . import DOMAIN, ClimateEntity
from . import DOMAIN

INTENT_GET_TEMPERATURE = "HassClimateGetTemperature"

Expand All @@ -23,82 +22,35 @@ class GetTemperatureIntent(intent.IntentHandler):

intent_type = INTENT_GET_TEMPERATURE
description = "Gets the current temperature of a climate device or entity"
slot_schema = {vol.Optional("area"): str, vol.Optional("name"): str}
slot_schema = {
vol.Optional("area"): intent.non_empty_string,
vol.Optional("name"): intent.non_empty_string,
}
platforms = {DOMAIN}

async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
"""Handle the intent."""
hass = intent_obj.hass
slots = self.async_validate_slots(intent_obj.slots)

component: EntityComponent[ClimateEntity] = hass.data[DOMAIN]
entities: list[ClimateEntity] = list(component.entities)
climate_entity: ClimateEntity | None = None
climate_state: State | None = None
name: str | None = None
if "name" in slots:
name = slots["name"]["value"]

if not entities:
raise intent.IntentHandleError("No climate entities")
area: str | None = None
if "area" in slots:
area = slots["area"]["value"]

name_slot = slots.get("name", {})
entity_name: str | None = name_slot.get("value")
entity_text: str | None = name_slot.get("text")

area_slot = slots.get("area", {})
area_id = area_slot.get("value")

if area_id:
# Filter by area and optionally name
area_name = area_slot.get("text")

for maybe_climate in intent.async_match_states(
hass, name=entity_name, area_name=area_id, domains=[DOMAIN]
):
climate_state = maybe_climate
break

if climate_state is None:
raise intent.NoStatesMatchedError(
reason=intent.MatchFailedReason.AREA,
name=entity_text or entity_name,
area=area_name or area_id,
floor=None,
domains={DOMAIN},
device_classes=None,
)

climate_entity = component.get_entity(climate_state.entity_id)
elif entity_name:
# Filter by name
for maybe_climate in intent.async_match_states(
hass, name=entity_name, domains=[DOMAIN]
):
climate_state = maybe_climate
break

if climate_state is None:
raise intent.NoStatesMatchedError(
reason=intent.MatchFailedReason.NAME,
name=entity_name,
area=None,
floor=None,
domains={DOMAIN},
device_classes=None,
)

climate_entity = component.get_entity(climate_state.entity_id)
else:
# First entity
climate_entity = entities[0]
climate_state = hass.states.get(climate_entity.entity_id)

assert climate_entity is not None

if climate_state is None:
raise intent.IntentHandleError(f"No state for {climate_entity.name}")

assert climate_state is not None
match_constraints = intent.MatchTargetsConstraints(
name=name, area_name=area, domains=[DOMAIN], assistant=intent_obj.assistant
)
match_result = intent.async_match_targets(hass, match_constraints)
if not match_result.is_match:
raise intent.MatchFailedError(
result=match_result, constraints=match_constraints
)

response = intent_obj.create_response()
response.response_type = intent.IntentResponseType.QUERY_ANSWER
response.async_set_states(matched_states=[climate_state])
response.async_set_states(matched_states=match_result.states)
return response
11 changes: 9 additions & 2 deletions homeassistant/components/conversation/default_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,15 @@ def _recognize(
intent_context=intent_context,
language=language,
):
if ("name" in result.entities) and (
not result.entities["name"].is_wildcard
# Prioritize results with a "name" slot, but still prefer ones with
# more literal text matched.
if (
("name" in result.entities)
and (not result.entities["name"].is_wildcard)
and (
(name_result is None)
or (result.text_chunks_matched > name_result.text_chunks_matched)
)
):
name_result = result

Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/egardia/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class EgardiaAlarm(AlarmControlPanelEntity):
"""Representation of a Egardia alarm."""

_attr_state: str | None
_attr_code_arm_required = False
_attr_supported_features = (
AlarmControlPanelEntityFeature.ARM_HOME
| AlarmControlPanelEntityFeature.ARM_AWAY
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/google_assistant_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ async def async_process(
await session.async_ensure_token_valid()
self.assistant = None
if not self.assistant or user_input.language != self.language:
credentials = Credentials(session.token[CONF_ACCESS_TOKEN])
credentials = Credentials(session.token[CONF_ACCESS_TOKEN]) # type: ignore[no-untyped-call]
self.language = user_input.language
self.assistant = TextAssistant(credentials, self.language)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/google_assistant_sdk/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async def async_send_text_commands(
entry.async_start_reauth(hass)
raise

credentials = Credentials(session.token[CONF_ACCESS_TOKEN])
credentials = Credentials(session.token[CONF_ACCESS_TOKEN]) # type: ignore[no-untyped-call]
language_code = entry.options.get(CONF_LANGUAGE_CODE, default_language_code(hass))
with TextAssistant(
credentials, language_code, audio_out=bool(media_players)
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/google_sheets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ async def async_setup_service(hass: HomeAssistant) -> None:

def _append_to_sheet(call: ServiceCall, entry: ConfigEntry) -> None:
"""Run append in the executor."""
service = Client(Credentials(entry.data[CONF_TOKEN][CONF_ACCESS_TOKEN]))
service = Client(
Credentials(entry.data[CONF_TOKEN][CONF_ACCESS_TOKEN]) # type: ignore[no-untyped-call]
)
try:
sheet = service.open_by_key(entry.unique_id)
except RefreshError:
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/google_sheets/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ async def async_step_reauth_confirm(

async def async_oauth_create_entry(self, data: dict[str, Any]) -> ConfigFlowResult:
"""Create an entry for the flow, or update existing entry."""
service = Client(Credentials(data[CONF_TOKEN][CONF_ACCESS_TOKEN]))
service = Client(
Credentials(data[CONF_TOKEN][CONF_ACCESS_TOKEN]) # type: ignore[no-untyped-call]
)

if self.reauth_entry:
_LOGGER.debug("service.open_by_key")
Expand Down
7 changes: 3 additions & 4 deletions homeassistant/components/hassio/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,14 @@ def add_issue(self, issue: Issue) -> None:
placeholders = {PLACEHOLDER_KEY_REFERENCE: issue.reference}

if issue.key == ISSUE_KEY_ADDON_DETACHED_ADDON_MISSING:
placeholders[PLACEHOLDER_KEY_ADDON_URL] = (
f"/hassio/addon/{issue.reference}"
)
addons = get_addons_info(self._hass)
if addons and issue.reference in addons:
placeholders[PLACEHOLDER_KEY_ADDON] = addons[issue.reference][
"name"
]
if "url" in addons[issue.reference]:
placeholders[PLACEHOLDER_KEY_ADDON_URL] = addons[
issue.reference
]["url"]
else:
placeholders[PLACEHOLDER_KEY_ADDON] = issue.reference

Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/hive/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class HiveAlarmControlPanelEntity(HiveEntity, AlarmControlPanelEntity):
| AlarmControlPanelEntityFeature.ARM_AWAY
| AlarmControlPanelEntityFeature.TRIGGER
)
_attr_code_arm_required = False

async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/holiday/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/holiday",
"iot_class": "local_polling",
"requirements": ["holidays==0.49", "babel==2.13.1"]
"requirements": ["holidays==0.50", "babel==2.13.1"]
}
1 change: 0 additions & 1 deletion homeassistant/components/http/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"domain": "http",
"name": "HTTP",
"after_dependencies": ["isal"],
"codeowners": ["@home-assistant/core"],
"documentation": "https://www.home-assistant.io/integrations/http",
"integration_type": "system",
Expand Down
45 changes: 23 additions & 22 deletions homeassistant/components/humidifier/intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class HumidityHandler(intent.IntentHandler):
intent_type = INTENT_HUMIDITY
description = "Set desired humidity level"
slot_schema = {
vol.Required("name"): cv.string,
vol.Required("name"): intent.non_empty_string,
vol.Required("humidity"): vol.All(vol.Coerce(int), vol.Range(0, 100)),
}
platforms = {DOMAIN}
Expand All @@ -44,18 +44,19 @@ async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse
"""Handle the hass intent."""
hass = intent_obj.hass
slots = self.async_validate_slots(intent_obj.slots)
states = list(
intent.async_match_states(
hass,
name=slots["name"]["value"],
states=hass.states.async_all(DOMAIN),
)
)

if not states:
raise intent.IntentHandleError("No entities matched")
match_constraints = intent.MatchTargetsConstraints(
name=slots["name"]["value"],
domains=[DOMAIN],
assistant=intent_obj.assistant,
)
match_result = intent.async_match_targets(hass, match_constraints)
if not match_result.is_match:
raise intent.MatchFailedError(
result=match_result, constraints=match_constraints
)

state = states[0]
state = match_result.states[0]
service_data = {ATTR_ENTITY_ID: state.entity_id}

humidity = slots["humidity"]["value"]
Expand Down Expand Up @@ -89,7 +90,7 @@ class SetModeHandler(intent.IntentHandler):
intent_type = INTENT_MODE
description = "Set humidifier mode"
slot_schema = {
vol.Required("name"): cv.string,
vol.Required("name"): intent.non_empty_string,
vol.Required("mode"): cv.string,
}
platforms = {DOMAIN}
Expand All @@ -98,18 +99,18 @@ async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse
"""Handle the hass intent."""
hass = intent_obj.hass
slots = self.async_validate_slots(intent_obj.slots)
states = list(
intent.async_match_states(
hass,
name=slots["name"]["value"],
states=hass.states.async_all(DOMAIN),
)
match_constraints = intent.MatchTargetsConstraints(
name=slots["name"]["value"],
domains=[DOMAIN],
assistant=intent_obj.assistant,
)
match_result = intent.async_match_targets(hass, match_constraints)
if not match_result.is_match:
raise intent.MatchFailedError(
result=match_result, constraints=match_constraints
)

if not states:
raise intent.IntentHandleError("No entities matched")

state = states[0]
state = match_result.states[0]
service_data = {ATTR_ENTITY_ID: state.entity_id}

intent.async_test_feature(state, HumidifierEntityFeature.MODES, "modes")
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/hydrawise/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/hydrawise",
"iot_class": "cloud_polling",
"loggers": ["pydrawise"],
"requirements": ["pydrawise==2024.6.2"]
"requirements": ["pydrawise==2024.6.3"]
}
Loading

0 comments on commit b28cdcf

Please sign in to comment.