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
7 changes: 4 additions & 3 deletions homeassistant/components/bang_olufsen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: BangOlufsenConfigEntry)
# Add the websocket and API client
entry.runtime_data = BangOlufsenData(websocket, client)

# Start WebSocket connection
await client.connect_notifications(remote_control=True, reconnect=True)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

# Start WebSocket connection once the platforms have been loaded.
# This ensures that the initial WebSocket notifications are dispatched to entities
await client.connect_notifications(remote_control=True, reconnect=True)

return True


Expand Down
29 changes: 2 additions & 27 deletions homeassistant/components/bang_olufsen/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ async def async_setup_entry(
async_add_entities(
new_entities=[
BangOlufsenMediaPlayer(config_entry, config_entry.runtime_data.client)
]
],
update_before_add=True,
)

# Register actions.
Expand Down Expand Up @@ -266,34 +267,8 @@ async def _initialize(self) -> None:
self._software_status.software_version,
)

# Get overall device state once. This is handled by WebSocket events the rest of the time.
product_state = await self._client.get_product_state()

# Get volume information.
if product_state.volume:
self._volume = product_state.volume

# Get all playback information.
# Ensure that the metadata is not None upon startup
if product_state.playback:
if product_state.playback.metadata:
self._playback_metadata = product_state.playback.metadata
self._remote_leader = product_state.playback.metadata.remote_leader
if product_state.playback.progress:
self._playback_progress = product_state.playback.progress
if product_state.playback.source:
self._source_change = product_state.playback.source
if product_state.playback.state:
self._playback_state = product_state.playback.state
# Set initial state
if self._playback_state.value:
self._state = self._playback_state.value

self._attr_media_position_updated_at = utcnow()

# Get the highest resolution available of the given images.
self._media_image = get_highest_resolution_artwork(self._playback_metadata)

# If the device has been updated with new sources, then the API will fail here.
await self._async_update_sources()

Expand Down
2 changes: 0 additions & 2 deletions homeassistant/components/cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
CONF_ACME_SERVER,
CONF_ALEXA,
CONF_ALIASES,
CONF_CLOUDHOOK_SERVER,
CONF_COGNITO_CLIENT_ID,
CONF_ENTITY_CONFIG,
CONF_FILTER,
Expand Down Expand Up @@ -130,7 +129,6 @@
vol.Optional(CONF_ACCOUNT_LINK_SERVER): str,
vol.Optional(CONF_ACCOUNTS_SERVER): str,
vol.Optional(CONF_ACME_SERVER): str,
vol.Optional(CONF_CLOUDHOOK_SERVER): str,
vol.Optional(CONF_RELAYER_SERVER): str,
vol.Optional(CONF_REMOTESTATE_SERVER): str,
vol.Optional(CONF_SERVICEHANDLERS_SERVER): str,
Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/cloud/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
CONF_ACCOUNT_LINK_SERVER = "account_link_server"
CONF_ACCOUNTS_SERVER = "accounts_server"
CONF_ACME_SERVER = "acme_server"
CONF_CLOUDHOOK_SERVER = "cloudhook_server"
CONF_RELAYER_SERVER = "relayer_server"
CONF_REMOTESTATE_SERVER = "remotestate_server"
CONF_SERVICEHANDLERS_SERVER = "servicehandlers_server"
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/cloud/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"integration_type": "system",
"iot_class": "cloud_push",
"loggers": ["acme", "hass_nabucasa", "snitun"],
"requirements": ["hass-nabucasa==1.1.2"],
"requirements": ["hass-nabucasa==1.2.0"],
"single_config_entry": true
}
106 changes: 106 additions & 0 deletions homeassistant/components/co2signal/quality_scale.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
rules:
# Bronze
action-setup:
status: exempt
comment: |
The integration does not provide any actions.
appropriate-polling: done
brands: done
common-modules: done
config-flow-test-coverage:
status: todo
comment: |
Stale docstring and test name: `test_form_home` and reusing result.
Extract `async_setup_entry` into own fixture.
Avoid importing `config_flow` in tests.
Test reauth with errors
config-flow:
status: todo
comment: |
The config flow misses data descriptions.
Remove URLs from data descriptions, they should be replaced with placeholders.
Make use of Electricity Maps zone keys in country code as dropdown.
Make use of location selector for coordinates.
dependency-transparency: done
docs-actions:
status: exempt
comment: |
The integration does not provide any actions.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup:
status: exempt
comment: |
Entities of this integration do not explicitly subscribe to events.
entity-unique-id: done
has-entity-name: done
runtime-data: done
test-before-configure: done
test-before-setup: done
unique-config-entry: todo

# Silver
action-exceptions:
status: exempt
comment: |
The integration does not provide any actions.
config-entry-unloading: done
docs-configuration-parameters:
status: exempt
comment: |
The integration does not provide any additional options.
docs-installation-parameters: done
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: todo
reauthentication-flow: done
test-coverage:
status: todo
comment: |
Use `hass.config_entries.async_setup` instead of assert await `async_setup_component(hass, DOMAIN, {})`
`test_sensor` could use `snapshot_platform`

# Gold
devices: done
diagnostics: done
discovery-update-info:
status: exempt
comment: |
This integration cannot be discovered, it is a connecting to a cloud service.
discovery:
status: exempt
comment: |
This integration cannot be discovered, it is a connecting to a cloud service.
docs-data-update: done
docs-examples: done
docs-known-limitations: done
docs-supported-devices: done
docs-supported-functions: done
docs-troubleshooting: done
docs-use-cases: done
dynamic-devices:
status: exempt
comment: |
The integration connects to a single service per configuration entry.
entity-category: done
entity-device-class: done
entity-disabled-by-default: done
entity-translations: done
exception-translations: todo
icon-translations: todo
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: |
This integration does not raise any repairable issues.
stale-devices:
status: exempt
comment: |
This integration connect to a single device per configuration entry.

# Platinum
async-dependency: done
inject-websession: done
strict-typing: done
55 changes: 43 additions & 12 deletions homeassistant/components/config/config_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from collections.abc import Callable
from http import HTTPStatus
import logging
from typing import Any, NoReturn

from aiohttp import web
Expand All @@ -23,14 +24,22 @@
FlowManagerResourceView,
)
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.json import json_fragment
from homeassistant.helpers.json import (
JSON_DUMP,
find_paths_unserializable_data,
json_bytes,
json_fragment,
)
from homeassistant.loader import (
Integration,
IntegrationNotFound,
async_get_config_flows,
async_get_integrations,
async_get_loaded_integration,
)
from homeassistant.util.json import format_unserializable_data

_LOGGER = logging.getLogger(__name__)


@callback
Expand Down Expand Up @@ -402,18 +411,40 @@ def async_on_flow_init_remove(change_type: str, flow_id: str) -> None:
connection.subscriptions[msg["id"]] = hass.config_entries.flow.async_subscribe_flow(
async_on_flow_init_remove
)
connection.send_message(
websocket_api.event_message(
msg["id"],
[
{"type": None, "flow_id": flw["flow_id"], "flow": flw}
for flw in hass.config_entries.flow.async_progress()
if flw["context"]["source"]
not in (
config_entries.SOURCE_RECONFIGURE,
config_entries.SOURCE_USER,
try:
serialized_flows = [
json_bytes({"type": None, "flow_id": flw["flow_id"], "flow": flw})
for flw in hass.config_entries.flow.async_progress()
if flw["context"]["source"]
not in (
config_entries.SOURCE_RECONFIGURE,
config_entries.SOURCE_USER,
)
]
except (ValueError, TypeError):
# If we can't serialize, we'll filter out unserializable flows
serialized_flows = []
for flw in hass.config_entries.flow.async_progress():
if flw["context"]["source"] in (
config_entries.SOURCE_RECONFIGURE,
config_entries.SOURCE_USER,
):
continue
try:
serialized_flows.append(
json_bytes({"type": None, "flow_id": flw["flow_id"], "flow": flw})
)
],
except (ValueError, TypeError):
_LOGGER.error(
"Unable to serialize to JSON. Bad data found at %s",
format_unserializable_data(
find_paths_unserializable_data(flw, dump=JSON_DUMP)
),
)
continue
connection.send_message(
websocket_api.messages.construct_event_message(
msg["id"], b"".join((b"[", b",".join(serialized_flows), b"]"))
)
)
connection.send_result(msg["id"])
Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/homekit/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

reload:
reset_accessory:
target:
entity: {}
fields:
entity_id:
required: true
selector:
entity:
multiple: true

unpair:
fields:
Expand Down
8 changes: 7 additions & 1 deletion homeassistant/components/homekit/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@
},
"reset_accessory": {
"name": "Reset accessory",
"description": "Resets a HomeKit accessory."
"description": "Resets a HomeKit accessory.",
"fields": {
"entity_id": {
"name": "Entity",
"description": "Entity to reset."
}
}
},
"unpair": {
"name": "Unpair an accessory or bridge",
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/imeon_inverter/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@
},
"energy_battery_consumed": {
"default": "mdi:battery-arrow-down-outline"
},
"forecast_cons_remaining_today": {
"default": "mdi:chart-line"
},
"forecast_prod_remaining_today": {
"default": "mdi:chart-line"
}
},
"select": {
Expand Down
15 changes: 15 additions & 0 deletions homeassistant/components/imeon_inverter/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,21 @@
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2,
),
# Forecast
SensorEntityDescription(
key="forecast_cons_remaining_today",
translation_key="forecast_cons_remaining_today",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
suggested_display_precision=2,
),
SensorEntityDescription(
key="forecast_prod_remaining_today",
translation_key="forecast_prod_remaining_today",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
suggested_display_precision=2,
),
)


Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/imeon_inverter/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@
},
"energy_battery_consumed": {
"name": "Today battery-consumed energy"
},
"forecast_cons_remaining_today": {
"name": "Forecast remaining energy consumption for today"
},
"forecast_prod_remaining_today": {
"name": "Forecast remaining energy production for today"
}
},
"select": {
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/litterrobot/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set_sleep_mode:
target:
entity:
domain: vacuum
integration: litterrobot
fields:
enabled:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/media_extractor/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "calculated",
"loggers": ["yt_dlp"],
"quality_scale": "internal",
"requirements": ["yt-dlp[default]==2025.09.23"],
"requirements": ["yt-dlp[default]==2025.09.26"],
"single_config_entry": true
}
Loading
Loading