Skip to content

Commit

Permalink
Merge branch 'home-assistant:dev' into lektrico2
Browse files Browse the repository at this point in the history
  • Loading branch information
Lektrico authored Feb 22, 2024
2 parents 3a65043 + 88e9870 commit 6de2599
Show file tree
Hide file tree
Showing 23 changed files with 338 additions and 523 deletions.
7 changes: 6 additions & 1 deletion homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@
#
# Integrations providing core functionality:
"application_credentials",
"backup",
"frontend",
"hardware",
"logger",
Expand Down Expand Up @@ -149,6 +148,10 @@
# These integrations are set up if using the Supervisor
"hassio",
}
DEFAULT_INTEGRATIONS_NON_SUPERVISOR = {
# These integrations are set up if not using the Supervisor
"backup",
}
CRITICAL_INTEGRATIONS = {
# Recovery mode is activated if these integrations fail to set up
"frontend",
Expand Down Expand Up @@ -538,6 +541,8 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
# Add domains depending on if the Supervisor is used or not
if "SUPERVISOR" in os.environ:
domains.update(DEFAULT_INTEGRATIONS_SUPERVISOR)
else:
domains.update(DEFAULT_INTEGRATIONS_NON_SUPERVISOR)

return domains

Expand Down
20 changes: 8 additions & 12 deletions homeassistant/components/backup/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,23 @@

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Backup integration."""
if is_hassio(hass):
LOGGER.error(
"The backup integration is not supported on this installation method, "
"please remove it from your configuration"
)
return False

backup_manager = BackupManager(hass)
hass.data[DOMAIN] = backup_manager

with_hassio = is_hassio(hass)

async_register_websocket_handlers(hass, with_hassio)

if with_hassio:
if DOMAIN in config:
LOGGER.error(
"The backup integration is not supported on this installation method, "
"please remove it from your configuration"
)
return True

async def async_handle_create_service(call: ServiceCall) -> None:
"""Service handler for creating backups."""
await backup_manager.generate_backup()

hass.services.async_register(DOMAIN, "create", async_handle_create_service)

async_register_websocket_handlers(hass)
async_register_http_views(hass)

return True
53 changes: 2 additions & 51 deletions homeassistant/components/backup/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback

from .const import DOMAIN, LOGGER
from .const import DOMAIN
from .manager import BackupManager


@callback
def async_register_websocket_handlers(hass: HomeAssistant, with_hassio: bool) -> None:
def async_register_websocket_handlers(hass: HomeAssistant) -> None:
"""Register websocket commands."""
if with_hassio:
websocket_api.async_register_command(hass, handle_backup_end)
websocket_api.async_register_command(hass, handle_backup_start)
return

websocket_api.async_register_command(hass, handle_info)
websocket_api.async_register_command(hass, handle_create)
websocket_api.async_register_command(hass, handle_remove)
Expand Down Expand Up @@ -74,47 +69,3 @@ async def handle_create(
manager: BackupManager = hass.data[DOMAIN]
backup = await manager.generate_backup()
connection.send_result(msg["id"], backup)


@websocket_api.ws_require_user(only_supervisor=True)
@websocket_api.websocket_command({vol.Required("type"): "backup/start"})
@websocket_api.async_response
async def handle_backup_start(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Backup start notification."""
manager: BackupManager = hass.data[DOMAIN]
manager.backing_up = True
LOGGER.debug("Backup start notification")

try:
await manager.pre_backup_actions()
except Exception as err: # pylint: disable=broad-except
connection.send_error(msg["id"], "pre_backup_actions_failed", str(err))
return

connection.send_result(msg["id"])


@websocket_api.ws_require_user(only_supervisor=True)
@websocket_api.websocket_command({vol.Required("type"): "backup/end"})
@websocket_api.async_response
async def handle_backup_end(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Backup end notification."""
manager: BackupManager = hass.data[DOMAIN]
manager.backing_up = False
LOGGER.debug("Backup end notification")

try:
await manager.post_backup_actions()
except Exception as err: # pylint: disable=broad-except
connection.send_error(msg["id"], "post_backup_actions_failed", str(err))
return

connection.send_result(msg["id"])
14 changes: 13 additions & 1 deletion homeassistant/components/braviatv/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

from collections.abc import Awaitable, Callable, Coroutine, Iterable
from datetime import timedelta
from datetime import datetime, timedelta
from functools import wraps
import logging
from types import MappingProxyType
Expand Down Expand Up @@ -87,6 +87,8 @@ def __init__(
self.media_content_type: MediaType | None = None
self.media_uri: str | None = None
self.media_duration: int | None = None
self.media_position: int | None = None
self.media_position_updated_at: datetime | None = None
self.volume_level: float | None = None
self.volume_target: str | None = None
self.volume_muted = False
Expand Down Expand Up @@ -185,6 +187,16 @@ async def async_update_playing(self) -> None:
self.media_content_id = None
self.media_content_type = None
self.source = None
if start_datetime := playing_info.get("startDateTime"):
start_datetime = datetime.fromisoformat(start_datetime)
current_datetime = datetime.now().replace(tzinfo=start_datetime.tzinfo)
self.media_position = int(
(current_datetime - start_datetime).total_seconds()
)
self.media_position_updated_at = datetime.now()
else:
self.media_position = None
self.media_position_updated_at = None
if self.media_uri:
self.media_content_id = self.media_uri
if self.media_uri[:8] == "extInput":
Expand Down
11 changes: 11 additions & 0 deletions homeassistant/components/braviatv/media_player.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Media player support for Bravia TV integration."""
from __future__ import annotations

from datetime import datetime
from typing import Any

from homeassistant.components.media_player import (
Expand Down Expand Up @@ -111,6 +112,16 @@ def media_duration(self) -> int | None:
"""Duration of current playing media in seconds."""
return self.coordinator.media_duration

@property
def media_position(self) -> int | None:
"""Position of current playing media in seconds."""
return self.coordinator.media_position

@property
def media_position_updated_at(self) -> datetime | None:
"""When was the position of the current playing media valid."""
return self.coordinator.media_position_updated_at

async def async_turn_on(self) -> None:
"""Turn the device on."""
await self.coordinator.async_turn_on()
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/bring/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/bring",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["bring-api==0.3.1"]
"requirements": ["bring-api==0.4.1"]
}
4 changes: 1 addition & 3 deletions homeassistant/components/discord/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ async def async_step_reauth_confirm(
if user_input:
error, info = await _async_try_connect(user_input[CONF_API_TOKEN])
if info and (entry := await self.async_set_unique_id(str(info.id))):
self.hass.config_entries.async_update_entry(
return self.async_update_reload_and_abort(
entry, data=entry.data | user_input
)
await self.hass.config_entries.async_reload(entry.entry_id)
return self.async_abort(reason="reauth_successful")
if error:
errors["base"] = error

Expand Down
40 changes: 40 additions & 0 deletions homeassistant/components/recorder/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

from datetime import datetime as dt
import logging
from typing import Any, Literal, cast

import voluptuous as vol
Expand Down Expand Up @@ -45,6 +46,8 @@
)
from .util import PERIOD_SCHEMA, get_instance, resolve_period

_LOGGER: logging.Logger = logging.getLogger(__package__)

UNIT_SCHEMA = vol.Schema(
{
vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS),
Expand All @@ -70,6 +73,8 @@
def async_setup(hass: HomeAssistant) -> None:
"""Set up the recorder websocket API."""
websocket_api.async_register_command(hass, ws_adjust_sum_statistics)
websocket_api.async_register_command(hass, ws_backup_end)
websocket_api.async_register_command(hass, ws_backup_start)
websocket_api.async_register_command(hass, ws_change_statistics_unit)
websocket_api.async_register_command(hass, ws_clear_statistics)
websocket_api.async_register_command(hass, ws_get_statistic_during_period)
Expand Down Expand Up @@ -512,3 +517,38 @@ def ws_info(
"thread_running": is_running,
}
connection.send_result(msg["id"], recorder_info)


@websocket_api.ws_require_user(only_supervisor=True)
@websocket_api.websocket_command({vol.Required("type"): "backup/start"})
@websocket_api.async_response
async def ws_backup_start(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
) -> None:
"""Backup start notification."""

_LOGGER.info("Backup start notification, locking database for writes")
instance = get_instance(hass)
try:
await instance.lock_database()
except TimeoutError as err:
connection.send_error(msg["id"], "timeout_error", str(err))
return
connection.send_result(msg["id"])


@websocket_api.ws_require_user(only_supervisor=True)
@websocket_api.websocket_command({vol.Required("type"): "backup/end"})
@websocket_api.async_response
async def ws_backup_end(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
) -> None:
"""Backup end notification."""

instance = get_instance(hass)
_LOGGER.info("Backup end notification, releasing write lock")
if not instance.unlock_database():
connection.send_error(
msg["id"], "database_unlock_failed", "Failed to unlock database."
)
connection.send_result(msg["id"])
2 changes: 1 addition & 1 deletion homeassistant/components/rova/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/rova",
"iot_class": "cloud_polling",
"loggers": ["rova"],
"requirements": ["rova==0.3.0"]
"requirements": ["rova==0.4.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/shelly/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def async_setup_block_attribute_entities(
continue

# Filter out non-existing sensors and sensors without a value
if getattr(block, sensor_id, None) in (-1, None):
if getattr(block, sensor_id, None) is None:
continue

# Filter and remove entities that according to settings
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/unifiprotect/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"iot_class": "local_push",
"loggers": ["pyunifiprotect", "unifi_discovery"],
"quality_scale": "platinum",
"requirements": ["pyunifiprotect==4.23.2", "unifi-discovery==1.1.7"],
"requirements": ["pyunifiprotect==4.23.3", "unifi-discovery==1.1.7"],
"ssdp": [
{
"manufacturer": "Ubiquiti Networks",
Expand Down
38 changes: 12 additions & 26 deletions homeassistant/components/vicare/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

from .const import DEVICE_LIST, DOMAIN
from .entity import ViCareEntity
from .types import ViCareDevice
from .types import HeatingProgram, ViCareDevice
from .utils import get_burners, get_circuits, get_compressors

_LOGGER = logging.getLogger(__name__)
Expand All @@ -58,15 +58,6 @@
VICARE_MODE_FORCEDNORMAL = "forcedNormal"
VICARE_MODE_OFF = "standby"

VICARE_PROGRAM_ACTIVE = "active"
VICARE_PROGRAM_COMFORT = "comfort"
VICARE_PROGRAM_ECO = "eco"
VICARE_PROGRAM_EXTERNAL = "external"
VICARE_PROGRAM_HOLIDAY = "holiday"
VICARE_PROGRAM_NORMAL = "normal"
VICARE_PROGRAM_REDUCED = "reduced"
VICARE_PROGRAM_STANDBY = "standby"

VICARE_HOLD_MODE_AWAY = "away"
VICARE_HOLD_MODE_HOME = "home"
VICARE_HOLD_MODE_OFF = "off"
Expand All @@ -85,18 +76,13 @@
}

VICARE_TO_HA_PRESET_HEATING = {
VICARE_PROGRAM_COMFORT: PRESET_COMFORT,
VICARE_PROGRAM_ECO: PRESET_ECO,
VICARE_PROGRAM_NORMAL: PRESET_HOME,
VICARE_PROGRAM_REDUCED: PRESET_SLEEP,
HeatingProgram.COMFORT: PRESET_COMFORT,
HeatingProgram.ECO: PRESET_ECO,
HeatingProgram.NORMAL: PRESET_HOME,
HeatingProgram.REDUCED: PRESET_SLEEP,
}

HA_TO_VICARE_PRESET_HEATING = {
PRESET_COMFORT: VICARE_PROGRAM_COMFORT,
PRESET_ECO: VICARE_PROGRAM_ECO,
PRESET_HOME: VICARE_PROGRAM_NORMAL,
PRESET_SLEEP: VICARE_PROGRAM_REDUCED,
}
HA_TO_VICARE_PRESET_HEATING = {v: k for k, v in VICARE_TO_HA_PRESET_HEATING.items()}


def _build_entities(
Expand Down Expand Up @@ -319,9 +305,9 @@ def set_preset_mode(self, preset_mode: str) -> None:

_LOGGER.debug("Current preset %s", self._current_program)
if self._current_program and self._current_program not in [
VICARE_PROGRAM_NORMAL,
VICARE_PROGRAM_REDUCED,
VICARE_PROGRAM_STANDBY,
HeatingProgram.NORMAL,
HeatingProgram.REDUCED,
HeatingProgram.STANDBY,
]:
# We can't deactivate "normal", "reduced" or "standby"
_LOGGER.debug("deactivating %s", self._current_program)
Expand All @@ -338,9 +324,9 @@ def set_preset_mode(self, preset_mode: str) -> None:

_LOGGER.debug("Setting preset to %s / %s", preset_mode, target_program)
if target_program not in [
VICARE_PROGRAM_NORMAL,
VICARE_PROGRAM_REDUCED,
VICARE_PROGRAM_STANDBY,
HeatingProgram.NORMAL,
HeatingProgram.REDUCED,
HeatingProgram.STANDBY,
]:
# And we can't explicitly activate "normal", "reduced" or "standby", either
_LOGGER.debug("activating %s", target_program)
Expand Down
Loading

0 comments on commit 6de2599

Please sign in to comment.