Skip to content

Commit

Permalink
Merge branch 'home-assistant:dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
grace43 committed Oct 9, 2023
2 parents e3ca9f8 + e6e190e commit 2da8f64
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 47 deletions.
24 changes: 24 additions & 0 deletions homeassistant/components/litterrobot/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,30 @@
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"issues": {
"service_deprecation_turn_off": {
"title": "Litter-Robot vaccum support for {old_service} is being removed",
"fix_flow": {
"step": {
"confirm": {
"title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]",
"description": "Litter-Robot vaccum support for the {old_service} service is deprecated and will be removed in Home Assistant 2024.2; Please adjust any automation or script that uses the service to instead call {new_service} and select submit below to mark this issue as resolved."
}
}
}
},
"service_deprecation_turn_on": {
"title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]",
"fix_flow": {
"step": {
"confirm": {
"title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]",
"description": "[%key:component::litterrobot::issues::service_deprecation_turn_off::fix_flow::step::confirm::description%]"
}
}
}
}
},
"entity": {
"binary_sensor": {
"sleeping": {
Expand Down
41 changes: 39 additions & 2 deletions homeassistant/components/litterrobot/vacuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_OFF
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers import (
config_validation as cv,
entity_platform,
issue_registry as ir,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
import homeassistant.util.dt as dt_util

Expand Down Expand Up @@ -77,7 +81,7 @@ class LitterRobotCleaner(LitterRobotEntity[LitterRobot], StateVacuumEntity):
_attr_supported_features = (
VacuumEntityFeature.START
| VacuumEntityFeature.STATE
| VacuumEntityFeature.STATUS
| VacuumEntityFeature.STOP
| VacuumEntityFeature.TURN_OFF
| VacuumEntityFeature.TURN_ON
)
Expand All @@ -97,15 +101,48 @@ def status(self) -> str:
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the cleaner on, starting a clean cycle."""
await self.robot.set_power_status(True)
ir.async_create_issue(
self.hass,
DOMAIN,
"service_deprecation_turn_on",
breaks_in_ha_version="2024.2.0",
is_fixable=True,
is_persistent=True,
severity=ir.IssueSeverity.WARNING,
translation_key="service_deprecation_turn_on",
translation_placeholders={
"old_service": "vacuum.turn_on",
"new_service": "vacuum.start",
},
)

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the unit off, stopping any cleaning in progress as is."""
await self.robot.set_power_status(False)
ir.async_create_issue(
self.hass,
DOMAIN,
"service_deprecation_turn_off",
breaks_in_ha_version="2024.2.0",
is_fixable=True,
is_persistent=True,
severity=ir.IssueSeverity.WARNING,
translation_key="service_deprecation_turn_off",
translation_placeholders={
"old_service": "vacuum.turn_off",
"new_service": "vacuum.stop",
},
)

async def async_start(self) -> None:
"""Start a clean cycle."""
await self.robot.set_power_status(True)
await self.robot.start_cleaning()

async def async_stop(self, **kwargs: Any) -> None:
"""Stop the vacuum cleaner."""
await self.robot.set_power_status(False)

async def async_set_sleep_mode(
self, enabled: bool, start_time: str | None = None
) -> None:
Expand Down
27 changes: 18 additions & 9 deletions homeassistant/components/switchbot_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ class SwitchbotCloudData:
devices: SwitchbotDevices


def prepare_device(
hass: HomeAssistant,
api: SwitchBotAPI,
device: Device | Remote,
coordinators: list[SwitchBotCoordinator],
) -> tuple[Device | Remote, SwitchBotCoordinator]:
"""Instantiate coordinator and adds to list for gathering."""
coordinator = SwitchBotCoordinator(hass, api, device)
coordinators.append(coordinator)
return (device, coordinator)


async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
"""Set up SwitchBot via API from a config entry."""
token = config.data[CONF_API_TOKEN]
Expand All @@ -48,28 +60,25 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
except CannotConnect as ex:
raise ConfigEntryNotReady from ex
_LOGGER.debug("Devices: %s", devices)
devices_and_coordinators = [
(device, SwitchBotCoordinator(hass, api, device)) for device in devices
]
coordinators: list[SwitchBotCoordinator] = []
hass.data.setdefault(DOMAIN, {})
data = SwitchbotCloudData(
api=api,
devices=SwitchbotDevices(
switches=[
(device, coordinator)
for device, coordinator in devices_and_coordinators
prepare_device(hass, api, device, coordinators)
for device in devices
if isinstance(device, Device)
and device.device_type.startswith("Plug")
or isinstance(device, Remote)
],
),
)
hass.data[DOMAIN][config.entry_id] = data
_LOGGER.debug("Switches: %s", data.devices.switches)
for device_type, devices in vars(data.devices).items():
_LOGGER.debug("%s: %s", device_type, devices)
await hass.config_entries.async_forward_entry_setups(config, PLATFORMS)
await gather(
*[coordinator.async_refresh() for _, coordinator in devices_and_coordinators]
)
await gather(*[coordinator.async_refresh() for coordinator in coordinators])
return True


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/switchbot_cloud/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/switchbot_cloud",
"iot_class": "cloud_polling",
"loggers": ["switchbot-api"],
"requirements": ["switchbot-api==1.1.0"]
"requirements": ["switchbot-api==1.2.1"]
}
15 changes: 0 additions & 15 deletions homeassistant/util/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,6 @@
_T = TypeVar("_T")


class HideSensitiveDataFilter(logging.Filter):
"""Filter API password calls."""

def __init__(self, text: str) -> None:
"""Initialize sensitive data filter."""
super().__init__()
self.text = text

def filter(self, record: logging.LogRecord) -> bool:
"""Hide sensitive data in messages."""
record.msg = record.msg.replace(self.text, "*******")

return True


class HomeAssistantQueueHandler(logging.handlers.QueueHandler):
"""Process the log in another thread."""

Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2517,7 +2517,7 @@ surepy==0.8.0
swisshydrodata==0.1.0

# homeassistant.components.switchbot_cloud
switchbot-api==1.1.0
switchbot-api==1.2.1

# homeassistant.components.synology_srm
synology-srm==0.2.0
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,7 @@ sunwatcher==0.2.1
surepy==0.8.0

# homeassistant.components.switchbot_cloud
switchbot-api==1.1.0
switchbot-api==1.2.1

# homeassistant.components.system_bridge
systembridgeconnector==3.8.4
Expand Down
72 changes: 67 additions & 5 deletions tests/components/litterrobot/test_vacuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
ATTR_STATUS,
DOMAIN as PLATFORM_DOMAIN,
SERVICE_START,
SERVICE_STOP,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_DOCKED,
STATE_ERROR,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
import homeassistant.helpers.entity_registry as er
from homeassistant.helpers import entity_registry as er, issue_registry as ir

from .common import VACUUM_ENTITY_ID
from .conftest import setup_integration
Expand Down Expand Up @@ -98,8 +99,17 @@ async def test_vacuum_with_error(
("service", "command", "extra"),
[
(SERVICE_START, "start_cleaning", None),
(SERVICE_TURN_OFF, "set_power_status", None),
(SERVICE_TURN_ON, "set_power_status", None),
(SERVICE_STOP, "set_power_status", None),
(
SERVICE_TURN_OFF,
"set_power_status",
{"issues": {(DOMAIN, "service_deprecation_turn_off")}},
),
(
SERVICE_TURN_ON,
"set_power_status",
{"issues": {(DOMAIN, "service_deprecation_turn_on")}},
),
(
SERVICE_SET_SLEEP_MODE,
"set_sleep_mode",
Expand All @@ -126,7 +136,7 @@ async def test_commands(

extra = extra or {}
data = {ATTR_ENTITY_ID: VACUUM_ENTITY_ID, **extra.get("data", {})}
deprecated = extra.get("deprecated", False)
issues = extra.get("issues", set())

await hass.services.async_call(
COMPONENT_SERVICE_DOMAIN.get(service, PLATFORM_DOMAIN),
Expand All @@ -135,4 +145,56 @@ async def test_commands(
blocking=True,
)
getattr(mock_account.robots[0], command).assert_called_once()
assert (f"'{DOMAIN}.{service}' service is deprecated" in caplog.text) is deprecated

issue_registry = ir.async_get(hass)
assert set(issue_registry.issues.keys()) == issues


@pytest.mark.parametrize(
("service", "issue_id", "placeholders"),
[
(
SERVICE_TURN_OFF,
"service_deprecation_turn_off",
{
"old_service": "vacuum.turn_off",
"new_service": "vacuum.stop",
},
),
(
SERVICE_TURN_ON,
"service_deprecation_turn_on",
{
"old_service": "vacuum.turn_on",
"new_service": "vacuum.start",
},
),
],
)
async def test_issues(
hass: HomeAssistant,
mock_account: MagicMock,
caplog: pytest.LogCaptureFixture,
service: str,
issue_id: str,
placeholders: dict[str, str],
) -> None:
"""Test issues raised by calling deprecated services."""
await setup_integration(hass, mock_account, PLATFORM_DOMAIN)

vacuum = hass.states.get(VACUUM_ENTITY_ID)
assert vacuum
assert vacuum.state == STATE_DOCKED

await hass.services.async_call(
PLATFORM_DOMAIN,
service,
{ATTR_ENTITY_ID: VACUUM_ENTITY_ID},
blocking=True,
)

issue_registry = ir.async_get(hass)
issue = issue_registry.async_get_issue(DOMAIN, issue_id)
assert issue.is_fixable is True
assert issue.is_persistent is True
assert issue.translation_placeholders == placeholders
13 changes: 0 additions & 13 deletions tests/util/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@
import homeassistant.util.logging as logging_util


def test_sensitive_data_filter() -> None:
"""Test the logging sensitive data filter."""
log_filter = logging_util.HideSensitiveDataFilter("mock_sensitive")

clean_record = logging.makeLogRecord({"msg": "clean log data"})
log_filter.filter(clean_record)
assert clean_record.msg == "clean log data"

sensitive_record = logging.makeLogRecord({"msg": "mock_sensitive log"})
log_filter.filter(sensitive_record)
assert sensitive_record.msg == "******* log"


async def test_logging_with_queue_handler() -> None:
"""Test logging with HomeAssistantQueueHandler."""

Expand Down

0 comments on commit 2da8f64

Please sign in to comment.