Fix smart by bond detection with v3 firmware (#73414)

This commit is contained in:
Marcio Granzotto Rodrigues 2022-06-12 22:27:18 -03:00 committed by GitHub
parent 42d39d2c7e
commit 5854dfa84f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 33 deletions

View File

@ -3,7 +3,7 @@
"name": "Bond",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bond",
"requirements": ["bond-async==0.1.20"],
"requirements": ["bond-async==0.1.22"],
"zeroconf": ["_bond._tcp.local."],
"codeowners": ["@bdraco", "@prystupa", "@joshs85", "@marciogranzotto"],
"quality_scale": "platinum",

View File

@ -5,7 +5,7 @@ import logging
from typing import Any, cast
from aiohttp import ClientResponseError
from bond_async import Action, Bond
from bond_async import Action, Bond, BondType
from homeassistant.util.async_ import gather_with_concurrency
@ -224,4 +224,5 @@ class BondHub:
@property
def is_bridge(self) -> bool:
"""Return if the Bond is a Bond Bridge."""
return bool(self._bridge)
bondid = self._version["bondid"]
return bool(BondType.is_bridge_from_serial(bondid))

View File

@ -420,7 +420,7 @@ blockchain==1.4.4
# bluepy==1.3.0
# homeassistant.components.bond
bond-async==0.1.20
bond-async==0.1.22
# homeassistant.components.bosch_shc
boschshcpy==0.2.30

View File

@ -321,7 +321,7 @@ blebox_uniapi==1.3.3
blinkpy==0.19.0
# homeassistant.components.bond
bond-async==0.1.20
bond-async==0.1.22
# homeassistant.components.bosch_shc
boschshcpy==0.2.30

View File

@ -127,7 +127,7 @@ def patch_bond_version(
return nullcontext()
if return_value is None:
return_value = {"bondid": "test-bond-id"}
return_value = {"bondid": "ZXXX12345"}
return patch(
"homeassistant.components.bond.Bond.version",

View File

@ -35,7 +35,7 @@ async def test_user_form(hass: core.HomeAssistant):
assert result["errors"] == {}
with patch_bond_version(
return_value={"bondid": "test-bond-id"}
return_value={"bondid": "ZXXX12345"}
), patch_bond_device_ids(
return_value=["f6776c11", "f6776c12"]
), patch_bond_bridge(), patch_bond_device_properties(), patch_bond_device(), _patch_async_setup_entry() as mock_setup_entry:
@ -64,7 +64,7 @@ async def test_user_form_with_non_bridge(hass: core.HomeAssistant):
assert result["errors"] == {}
with patch_bond_version(
return_value={"bondid": "test-bond-id"}
return_value={"bondid": "KXXX12345"}
), patch_bond_device_ids(
return_value=["f6776c11"]
), patch_bond_device_properties(), patch_bond_device(
@ -96,7 +96,7 @@ async def test_user_form_invalid_auth(hass: core.HomeAssistant):
)
with patch_bond_version(
return_value={"bond_id": "test-bond-id"}
return_value={"bond_id": "ZXXX12345"}
), patch_bond_bridge(), patch_bond_device_ids(
side_effect=ClientResponseError(Mock(), Mock(), status=401),
):
@ -203,7 +203,7 @@ async def test_zeroconf_form(hass: core.HomeAssistant):
host="test-host",
addresses=["test-host"],
hostname="mock_hostname",
name="test-bond-id.some-other-tail-info",
name="ZXXX12345.some-other-tail-info",
port=None,
properties={},
type="mock_type",
@ -213,7 +213,7 @@ async def test_zeroconf_form(hass: core.HomeAssistant):
assert result["errors"] == {}
with patch_bond_version(
return_value={"bondid": "test-bond-id"}
return_value={"bondid": "ZXXX12345"}
), patch_bond_bridge(), patch_bond_device_ids(), _patch_async_setup_entry() as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
@ -241,7 +241,7 @@ async def test_zeroconf_form_token_unavailable(hass: core.HomeAssistant):
host="test-host",
addresses=["test-host"],
hostname="mock_hostname",
name="test-bond-id.some-other-tail-info",
name="ZXXX12345.some-other-tail-info",
port=None,
properties={},
type="mock_type",
@ -270,7 +270,7 @@ async def test_zeroconf_form_token_unavailable(hass: core.HomeAssistant):
async def test_zeroconf_form_with_token_available(hass: core.HomeAssistant):
"""Test we get the discovery form when we can get the token."""
with patch_bond_version(return_value={"bondid": "test-bond-id"}), patch_bond_token(
with patch_bond_version(return_value={"bondid": "ZXXX12345"}), patch_bond_token(
return_value={"token": "discovered-token"}
), patch_bond_bridge(
return_value={"name": "discovered-name"}
@ -282,7 +282,7 @@ async def test_zeroconf_form_with_token_available(hass: core.HomeAssistant):
host="test-host",
addresses=["test-host"],
hostname="mock_hostname",
name="test-bond-id.some-other-tail-info",
name="ZXXX12345.some-other-tail-info",
port=None,
properties={},
type="mock_type",
@ -323,7 +323,7 @@ async def test_zeroconf_form_with_token_available_name_unavailable(
host="test-host",
addresses=["test-host"],
hostname="mock_hostname",
name="test-bond-id.some-other-tail-info",
name="ZXXX12345.some-other-tail-info",
port=None,
properties={},
type="mock_type",
@ -341,7 +341,7 @@ async def test_zeroconf_form_with_token_available_name_unavailable(
await hass.async_block_till_done()
assert result2["type"] == "create_entry"
assert result2["title"] == "test-bond-id"
assert result2["title"] == "ZXXX12345"
assert result2["data"] == {
CONF_HOST: "test-host",
CONF_ACCESS_TOKEN: "discovered-token",
@ -511,7 +511,7 @@ async def test_zeroconf_form_unexpected_error(hass: core.HomeAssistant):
host="test-host",
addresses=["test-host"],
hostname="mock_hostname",
name="test-bond-id.some-other-tail-info",
name="ZXXX12345.some-other-tail-info",
port=None,
properties={},
type="mock_type",
@ -536,7 +536,7 @@ async def _help_test_form_unexpected_error(
)
with patch_bond_version(
return_value={"bond_id": "test-bond-id"}
return_value={"bond_id": "ZXXX12345"}
), patch_bond_device_ids(side_effect=error):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input

View File

@ -39,5 +39,5 @@ async def test_diagnostics(hass, hass_client):
"data": {"access_token": "**REDACTED**", "host": "some host"},
"title": "Mock Title",
},
"hub": {"version": {"bondid": "test-bond-id"}},
"hub": {"version": {"bondid": "ZXXX12345"}},
}

View File

@ -9,7 +9,7 @@ import pytest
from homeassistant.components.bond.const import DOMAIN
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.const import ATTR_ASSUMED_STATE, CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity_registry import EntityRegistry
@ -86,7 +86,7 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAss
with patch_bond_bridge(), patch_bond_version(
return_value={
"bondid": "test-bond-id",
"bondid": "ZXXX12345",
"target": "test-model",
"fw_ver": "test-version",
"mcu_ver": "test-hw-version",
@ -104,11 +104,11 @@ async def test_async_setup_entry_sets_up_hub_and_supported_domains(hass: HomeAss
assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state is ConfigEntryState.LOADED
assert config_entry.unique_id == "test-bond-id"
assert config_entry.unique_id == "ZXXX12345"
# verify hub device is registered correctly
device_registry = dr.async_get(hass)
hub = device_registry.async_get_device(identifiers={(DOMAIN, "test-bond-id")})
hub = device_registry.async_get_device(identifiers={(DOMAIN, "ZXXX12345")})
assert hub.name == "bond-name"
assert hub.manufacturer == "Olibra"
assert hub.model == "test-model"
@ -156,7 +156,7 @@ async def test_old_identifiers_are_removed(hass: HomeAssistant):
)
old_identifers = (DOMAIN, "device_id")
new_identifiers = (DOMAIN, "test-bond-id", "device_id")
new_identifiers = (DOMAIN, "ZXXX12345", "device_id")
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
@ -169,7 +169,7 @@ async def test_old_identifiers_are_removed(hass: HomeAssistant):
with patch_bond_bridge(), patch_bond_version(
return_value={
"bondid": "test-bond-id",
"bondid": "ZXXX12345",
"target": "test-model",
"fw_ver": "test-version",
}
@ -190,7 +190,7 @@ async def test_old_identifiers_are_removed(hass: HomeAssistant):
assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state is ConfigEntryState.LOADED
assert config_entry.unique_id == "test-bond-id"
assert config_entry.unique_id == "ZXXX12345"
# verify the device info is cleaned up
assert device_registry.async_get_device(identifiers={old_identifers}) is None
@ -210,7 +210,7 @@ async def test_smart_by_bond_device_suggested_area(hass: HomeAssistant):
side_effect=ClientResponseError(Mock(), Mock(), status=404)
), patch_bond_version(
return_value={
"bondid": "test-bond-id",
"bondid": "KXXX12345",
"target": "test-model",
"fw_ver": "test-version",
}
@ -232,10 +232,10 @@ async def test_smart_by_bond_device_suggested_area(hass: HomeAssistant):
assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state is ConfigEntryState.LOADED
assert config_entry.unique_id == "test-bond-id"
assert config_entry.unique_id == "KXXX12345"
device_registry = dr.async_get(hass)
device = device_registry.async_get_device(identifiers={(DOMAIN, "test-bond-id")})
device = device_registry.async_get_device(identifiers={(DOMAIN, "KXXX12345")})
assert device is not None
assert device.suggested_area == "Den"
@ -256,7 +256,7 @@ async def test_bridge_device_suggested_area(hass: HomeAssistant):
}
), patch_bond_version(
return_value={
"bondid": "test-bond-id",
"bondid": "ZXXX12345",
"target": "test-model",
"fw_ver": "test-version",
}
@ -278,10 +278,10 @@ async def test_bridge_device_suggested_area(hass: HomeAssistant):
assert config_entry.entry_id in hass.data[DOMAIN]
assert config_entry.state is ConfigEntryState.LOADED
assert config_entry.unique_id == "test-bond-id"
assert config_entry.unique_id == "ZXXX12345"
device_registry = dr.async_get(hass)
device = device_registry.async_get_device(identifiers={(DOMAIN, "test-bond-id")})
device = device_registry.async_get_device(identifiers={(DOMAIN, "ZXXX12345")})
assert device is not None
assert device.suggested_area == "Office"
@ -343,3 +343,15 @@ async def test_device_remove_devices(hass, hass_ws_client):
)
is False
)
async def test_smart_by_bond_v3_firmware(hass: HomeAssistant) -> None:
"""Test we can detect smart by bond with the v3 firmware."""
await setup_platform(
hass,
FAN_DOMAIN,
ceiling_fan("name-1"),
bond_version={"bondid": "KXXXX12345", "target": "breck-northstar"},
bond_device_id="test-device-id",
)
assert ATTR_ASSUMED_STATE not in hass.states.get("fan.name_1").attributes

View File

@ -249,7 +249,7 @@ async def test_sbb_trust_state(hass: core.HomeAssistant):
"""Assumed state should be False if device is a Smart by Bond."""
version = {
"model": "MR123A",
"bondid": "test-bond-id",
"bondid": "KXXX12345",
}
await setup_platform(
hass, LIGHT_DOMAIN, ceiling_fan("name-1"), bond_version=version, bridge={}