Skip to content

Commit 4f88599

Browse files
authored
Remove deprecation for SmartThings binary sensor (home-assistant#156924)
1 parent 25e2c9e commit 4f88599

File tree

3 files changed

+45
-271
lines changed

3 files changed

+45
-271
lines changed

homeassistant/components/smartthings/binary_sensor.py

Lines changed: 44 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,17 @@
88
from pysmartthings import Attribute, Capability, Category, SmartThings, Status
99

1010
from homeassistant.components.binary_sensor import (
11-
DOMAIN as BINARY_SENSOR_DOMAIN,
1211
BinarySensorDeviceClass,
1312
BinarySensorEntity,
1413
BinarySensorEntityDescription,
1514
)
1615
from homeassistant.const import EntityCategory
1716
from homeassistant.core import HomeAssistant
18-
from homeassistant.helpers import entity_registry as er
1917
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
2018

2119
from . import FullDevice, SmartThingsConfigEntry
2220
from .const import INVALID_SWITCH_CATEGORIES, MAIN
2321
from .entity import SmartThingsEntity
24-
from .util import deprecate_entity
2522

2623

2724
@dataclass(frozen=True, kw_only=True)
@@ -31,11 +28,14 @@ class SmartThingsBinarySensorEntityDescription(BinarySensorEntityDescription):
3128
is_on_key: str
3229
category_device_class: dict[Category | str, BinarySensorDeviceClass] | None = None
3330
category: set[Category] | None = None
34-
exists_fn: Callable[[str], bool] | None = None
31+
exists_fn: (
32+
Callable[
33+
[str, dict[str, dict[Capability | str, dict[Attribute | str, Status]]]],
34+
bool,
35+
]
36+
| None
37+
) = None
3538
component_translation_key: dict[str, str] | None = None
36-
deprecated_fn: Callable[
37-
[dict[str, dict[Capability | str, dict[Attribute | str, Status]]]], str | None
38-
] = lambda _: None
3939

4040

4141
CAPABILITY_TO_SENSORS: dict[
@@ -59,17 +59,16 @@ class SmartThingsBinarySensorEntityDescription(BinarySensorEntityDescription):
5959
Category.DOOR: BinarySensorDeviceClass.DOOR,
6060
Category.WINDOW: BinarySensorDeviceClass.WINDOW,
6161
},
62-
exists_fn=lambda key: key in {"freezer", "cooler", "cvroom"},
62+
exists_fn=lambda component, status: (
63+
not ("freezer" in status and "cooler" in status)
64+
if component == MAIN
65+
else True
66+
),
6367
component_translation_key={
6468
"freezer": "freezer_door",
6569
"cooler": "cooler_door",
6670
"cvroom": "cool_select_plus_door",
6771
},
68-
deprecated_fn=(
69-
lambda status: "fridge_door"
70-
if "freezer" in status and "cooler" in status
71-
else None
72-
),
7372
)
7473
},
7574
Capability.CUSTOM_DRYER_WRINKLE_PREVENT: {
@@ -155,15 +154,6 @@ class SmartThingsBinarySensorEntityDescription(BinarySensorEntityDescription):
155154
entity_category=EntityCategory.DIAGNOSTIC,
156155
)
157156
},
158-
Capability.VALVE: {
159-
Attribute.VALVE: SmartThingsBinarySensorEntityDescription(
160-
key=Attribute.VALVE,
161-
translation_key="valve",
162-
device_class=BinarySensorDeviceClass.OPENING,
163-
is_on_key="open",
164-
deprecated_fn=lambda _: "valve",
165-
)
166-
},
167157
Capability.WATER_SENSOR: {
168158
Attribute.WATER: SmartThingsBinarySensorEntityDescription(
169159
key=Attribute.WATER,
@@ -204,64 +194,39 @@ async def async_setup_entry(
204194
) -> None:
205195
"""Add binary sensors for a config entry."""
206196
entry_data = entry.runtime_data
207-
entities = []
208-
209-
entity_registry = er.async_get(hass)
210197

211-
for device in entry_data.devices.values(): # pylint: disable=too-many-nested-blocks
212-
for capability, attribute_map in CAPABILITY_TO_SENSORS.items():
213-
for attribute, description in attribute_map.items():
214-
for component in device.status:
215-
if (
216-
capability in device.status[component]
217-
and (
218-
component == MAIN
219-
or (
220-
description.exists_fn is not None
221-
and description.exists_fn(component)
222-
)
223-
)
224-
and (
225-
not description.category
226-
or get_main_component_category(device)
227-
in description.category
228-
)
229-
):
230-
if (
231-
component == MAIN
232-
and (issue := description.deprecated_fn(device.status))
233-
is not None
234-
):
235-
if deprecate_entity(
236-
hass,
237-
entity_registry,
238-
BINARY_SENSOR_DOMAIN,
239-
f"{device.device.device_id}_{component}_{capability}_{attribute}_{attribute}",
240-
f"deprecated_binary_{issue}",
241-
):
242-
entities.append(
243-
SmartThingsBinarySensor(
244-
entry_data.client,
245-
device,
246-
description,
247-
capability,
248-
attribute,
249-
component,
250-
)
251-
)
252-
continue
253-
entities.append(
254-
SmartThingsBinarySensor(
255-
entry_data.client,
256-
device,
257-
description,
258-
capability,
259-
attribute,
260-
component,
261-
)
262-
)
263-
264-
async_add_entities(entities)
198+
async_add_entities(
199+
SmartThingsBinarySensor(
200+
entry_data.client,
201+
device,
202+
description,
203+
capability,
204+
attribute,
205+
component,
206+
)
207+
for device in entry_data.devices.values()
208+
for capability, attribute_map in CAPABILITY_TO_SENSORS.items()
209+
for attribute, description in attribute_map.items()
210+
for component in device.status
211+
if (
212+
capability in device.status[component]
213+
and (
214+
component == MAIN
215+
or (
216+
description.component_translation_key is not None
217+
and component in description.component_translation_key
218+
)
219+
)
220+
and (
221+
description.exists_fn is None
222+
or description.exists_fn(component, device.status)
223+
)
224+
and (
225+
not description.category
226+
or get_main_component_category(device) in description.category
227+
)
228+
)
229+
)
265230

266231

267232
class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity):

homeassistant/components/smartthings/strings.json

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -667,22 +667,6 @@
667667
}
668668
},
669669
"issues": {
670-
"deprecated_binary_fridge_door": {
671-
"description": "The refrigerator door binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. Separate entities for cooler and freezer door are available and should be used going forward. Please update your dashboards, templates accordingly and disable the entity to fix this issue.",
672-
"title": "Refrigerator door binary sensor deprecated"
673-
},
674-
"deprecated_binary_fridge_door_scripts": {
675-
"description": "The refrigerator door binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. The entity is used in the following automations or scripts:\n{items}\n\nSeparate entities for cooler and freezer door are available and should be used going forward. Please use them in the above automations or scripts and disable the entity to fix this issue.",
676-
"title": "[%key:component::smartthings::issues::deprecated_binary_fridge_door::title%]"
677-
},
678-
"deprecated_binary_valve": {
679-
"description": "The valve binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. A valve entity with controls is available and should be used going forward. Please update your dashboards, templates accordingly and disable the entity to fix this issue.",
680-
"title": "Valve binary sensor deprecated"
681-
},
682-
"deprecated_binary_valve_scripts": {
683-
"description": "The valve binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. The entity is used in the following automations or scripts:\n{items}\n\nA valve entity with controls is available and should be used going forward. Please use the new valve entity in the above automations or scripts and disable the entity to fix this issue.",
684-
"title": "[%key:component::smartthings::issues::deprecated_binary_valve::title%]"
685-
},
686670
"deprecated_dhw": {
687671
"description": "The sensor {entity_name} (`{entity_id}`) is deprecated because it has been replaced with a water heater entity.\n\nPlease update your dashboards and templates to use the new water heater entity and disable the sensor to fix this issue.",
688672
"title": "Water heater sensors deprecated"

tests/components/smartthings/test_binary_sensor.py

Lines changed: 1 addition & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,9 @@
77
import pytest
88
from syrupy.assertion import SnapshotAssertion
99

10-
from homeassistant.components import automation, script
11-
from homeassistant.components.automation import automations_with_entity
12-
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
13-
from homeassistant.components.script import scripts_with_entity
14-
from homeassistant.components.smartthings import DOMAIN, MAIN
1510
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, Platform
1611
from homeassistant.core import HomeAssistant
17-
from homeassistant.helpers import entity_registry as er, issue_registry as ir
18-
from homeassistant.setup import async_setup_component
12+
from homeassistant.helpers import entity_registry as er
1913

2014
from . import (
2115
setup_integration,
@@ -105,172 +99,3 @@ async def test_availability_at_start(
10599
hass.states.get("binary_sensor.refrigerator_fridge_door").state
106100
== STATE_UNAVAILABLE
107101
)
108-
109-
110-
@pytest.mark.parametrize(
111-
("device_fixture", "unique_id", "suggested_object_id", "issue_string", "entity_id"),
112-
[
113-
(
114-
"virtual_valve",
115-
f"612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3_{MAIN}_{Capability.VALVE}_{Attribute.VALVE}_{Attribute.VALVE}",
116-
"volvo_valve",
117-
"valve",
118-
"binary_sensor.volvo_valve",
119-
),
120-
(
121-
"da_ref_normal_000001",
122-
f"7db87911-7dce-1cf2-7119-b953432a2f09_{MAIN}_{Capability.CONTACT_SENSOR}_{Attribute.CONTACT}_{Attribute.CONTACT}",
123-
"refrigerator_door",
124-
"fridge_door",
125-
"binary_sensor.refrigerator_door",
126-
),
127-
],
128-
)
129-
async def test_create_issue_with_items(
130-
hass: HomeAssistant,
131-
devices: AsyncMock,
132-
mock_config_entry: MockConfigEntry,
133-
entity_registry: er.EntityRegistry,
134-
issue_registry: ir.IssueRegistry,
135-
unique_id: str,
136-
suggested_object_id: str,
137-
issue_string: str,
138-
entity_id: str,
139-
) -> None:
140-
"""Test we create an issue when an automation or script is using a deprecated entity."""
141-
issue_id = f"deprecated_binary_{issue_string}_{entity_id}"
142-
143-
entity_entry = entity_registry.async_get_or_create(
144-
BINARY_SENSOR_DOMAIN,
145-
DOMAIN,
146-
unique_id,
147-
suggested_object_id=suggested_object_id,
148-
original_name=suggested_object_id,
149-
)
150-
151-
assert await async_setup_component(
152-
hass,
153-
automation.DOMAIN,
154-
{
155-
automation.DOMAIN: {
156-
"id": "test",
157-
"alias": "test",
158-
"trigger": {"platform": "state", "entity_id": entity_id},
159-
"action": {
160-
"action": "automation.turn_on",
161-
"target": {
162-
"entity_id": "automation.test",
163-
},
164-
},
165-
}
166-
},
167-
)
168-
assert await async_setup_component(
169-
hass,
170-
script.DOMAIN,
171-
{
172-
script.DOMAIN: {
173-
"test": {
174-
"sequence": [
175-
{
176-
"condition": "state",
177-
"entity_id": entity_id,
178-
"state": "on",
179-
},
180-
],
181-
}
182-
}
183-
},
184-
)
185-
186-
await setup_integration(hass, mock_config_entry)
187-
188-
assert hass.states.get(entity_id).state == STATE_OFF
189-
190-
assert automations_with_entity(hass, entity_id)[0] == "automation.test"
191-
assert scripts_with_entity(hass, entity_id)[0] == "script.test"
192-
193-
issue = issue_registry.async_get_issue(DOMAIN, issue_id)
194-
assert issue is not None
195-
assert issue.translation_key == f"deprecated_binary_{issue_string}_scripts"
196-
assert issue.translation_placeholders == {
197-
"entity_id": entity_id,
198-
"entity_name": suggested_object_id,
199-
"items": "- [test](/config/automation/edit/test)\n- [test](/config/script/edit/test)",
200-
}
201-
202-
entity_registry.async_update_entity(
203-
entity_entry.entity_id,
204-
disabled_by=er.RegistryEntryDisabler.USER,
205-
)
206-
207-
await hass.config_entries.async_reload(mock_config_entry.entry_id)
208-
await hass.async_block_till_done()
209-
210-
# Assert the issue is no longer present
211-
assert not issue_registry.async_get_issue(DOMAIN, issue_id)
212-
213-
214-
@pytest.mark.parametrize(
215-
("device_fixture", "unique_id", "suggested_object_id", "issue_string", "entity_id"),
216-
[
217-
(
218-
"virtual_valve",
219-
f"612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3_{MAIN}_{Capability.VALVE}_{Attribute.VALVE}_{Attribute.VALVE}",
220-
"volvo_valve",
221-
"valve",
222-
"binary_sensor.volvo_valve",
223-
),
224-
(
225-
"da_ref_normal_000001",
226-
f"7db87911-7dce-1cf2-7119-b953432a2f09_{MAIN}_{Capability.CONTACT_SENSOR}_{Attribute.CONTACT}_{Attribute.CONTACT}",
227-
"refrigerator_door",
228-
"fridge_door",
229-
"binary_sensor.refrigerator_door",
230-
),
231-
],
232-
)
233-
async def test_create_issue(
234-
hass: HomeAssistant,
235-
devices: AsyncMock,
236-
mock_config_entry: MockConfigEntry,
237-
entity_registry: er.EntityRegistry,
238-
issue_registry: ir.IssueRegistry,
239-
unique_id: str,
240-
suggested_object_id: str,
241-
issue_string: str,
242-
entity_id: str,
243-
) -> None:
244-
"""Test we create an issue when an automation or script is using a deprecated entity."""
245-
issue_id = f"deprecated_binary_{issue_string}_{entity_id}"
246-
247-
entity_entry = entity_registry.async_get_or_create(
248-
BINARY_SENSOR_DOMAIN,
249-
DOMAIN,
250-
unique_id,
251-
suggested_object_id=suggested_object_id,
252-
original_name=suggested_object_id,
253-
)
254-
255-
await setup_integration(hass, mock_config_entry)
256-
257-
assert hass.states.get(entity_id).state == STATE_OFF
258-
259-
issue = issue_registry.async_get_issue(DOMAIN, issue_id)
260-
assert issue is not None
261-
assert issue.translation_key == f"deprecated_binary_{issue_string}"
262-
assert issue.translation_placeholders == {
263-
"entity_id": entity_id,
264-
"entity_name": suggested_object_id,
265-
}
266-
267-
entity_registry.async_update_entity(
268-
entity_entry.entity_id,
269-
disabled_by=er.RegistryEntryDisabler.USER,
270-
)
271-
272-
await hass.config_entries.async_reload(mock_config_entry.entry_id)
273-
await hass.async_block_till_done()
274-
275-
# Assert the issue is no longer present
276-
assert not issue_registry.async_get_issue(DOMAIN, issue_id)

0 commit comments

Comments
 (0)