Fix bond device state with v3 firmwares (#72516)

This commit is contained in:
Marcio Granzotto Rodrigues 2022-05-26 01:12:43 -03:00 committed by GitHub
parent 3537fa1dab
commit c1f62d03a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 59 additions and 31 deletions

View file

@ -5,7 +5,7 @@ import logging
from typing import Any from typing import Any
from aiohttp import ClientError, ClientResponseError, ClientTimeout from aiohttp import ClientError, ClientResponseError, ClientTimeout
from bond_api import Bond, BPUPSubscriptions, start_bpup from bond_async import Bond, BPUPSubscriptions, start_bpup
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (

View file

@ -5,7 +5,7 @@ from dataclasses import dataclass
import logging import logging
from typing import Any from typing import Any
from bond_api import Action, BPUPSubscriptions from bond_async import Action, BPUPSubscriptions
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry

View file

@ -6,7 +6,7 @@ import logging
from typing import Any from typing import Any
from aiohttp import ClientConnectionError, ClientResponseError from aiohttp import ClientConnectionError, ClientResponseError
from bond_api import Bond from bond_async import Bond
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries, exceptions from homeassistant import config_entries, exceptions

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from bond_api import Action, BPUPSubscriptions, DeviceType from bond_async import Action, BPUPSubscriptions, DeviceType
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, ATTR_POSITION,

View file

@ -8,7 +8,7 @@ import logging
from typing import Any from typing import Any
from aiohttp import ClientError from aiohttp import ClientError
from bond_api import BPUPSubscriptions from bond_async import BPUPSubscriptions
from homeassistant.const import ( from homeassistant.const import (
ATTR_HW_VERSION, ATTR_HW_VERSION,
@ -156,9 +156,13 @@ class BondEntity(Entity):
self._apply_state(state) self._apply_state(state)
@callback @callback
def _async_bpup_callback(self, state: dict) -> None: def _async_bpup_callback(self, json_msg: dict) -> None:
"""Process a state change from BPUP.""" """Process a state change from BPUP."""
self._async_state_callback(state) topic = json_msg["t"]
if topic != f"devices/{self._device_id}/state":
return
self._async_state_callback(json_msg["b"])
self.async_write_ha_state() self.async_write_ha_state()
async def async_added_to_hass(self) -> None: async def async_added_to_hass(self) -> None:

View file

@ -6,7 +6,7 @@ import math
from typing import Any from typing import Any
from aiohttp.client_exceptions import ClientResponseError from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType, Direction from bond_async import Action, BPUPSubscriptions, DeviceType, Direction
import voluptuous as vol import voluptuous as vol
from homeassistant.components.fan import ( from homeassistant.components.fan import (

View file

@ -5,7 +5,7 @@ import logging
from typing import Any from typing import Any
from aiohttp.client_exceptions import ClientResponseError from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType from bond_async import Action, BPUPSubscriptions, DeviceType
import voluptuous as vol import voluptuous as vol
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity

View file

@ -3,10 +3,10 @@
"name": "Bond", "name": "Bond",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bond", "documentation": "https://www.home-assistant.io/integrations/bond",
"requirements": ["bond-api==0.1.18"], "requirements": ["bond-async==0.1.20"],
"zeroconf": ["_bond._tcp.local."], "zeroconf": ["_bond._tcp.local."],
"codeowners": ["@bdraco", "@prystupa", "@joshs85", "@marciogranzotto"], "codeowners": ["@bdraco", "@prystupa", "@joshs85", "@marciogranzotto"],
"quality_scale": "platinum", "quality_scale": "platinum",
"iot_class": "local_push", "iot_class": "local_push",
"loggers": ["bond_api"] "loggers": ["bond_async"]
} }

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from aiohttp.client_exceptions import ClientResponseError from aiohttp.client_exceptions import ClientResponseError
from bond_api import Action, BPUPSubscriptions, DeviceType from bond_async import Action, BPUPSubscriptions, DeviceType
import voluptuous as vol import voluptuous as vol
from homeassistant.components.switch import SwitchEntity from homeassistant.components.switch import SwitchEntity

View file

@ -5,7 +5,7 @@ import logging
from typing import Any, cast from typing import Any, cast
from aiohttp import ClientResponseError from aiohttp import ClientResponseError
from bond_api import Action, Bond from bond_async import Action, Bond
from homeassistant.util.async_ import gather_with_concurrency from homeassistant.util.async_ import gather_with_concurrency

View file

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

View file

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

View file

@ -8,7 +8,7 @@ from typing import Any
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from aiohttp.client_exceptions import ClientResponseError from aiohttp.client_exceptions import ClientResponseError
from bond_api import DeviceType from bond_async import DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.bond.const import DOMAIN as BOND_DOMAIN from homeassistant.components.bond.const import DOMAIN as BOND_DOMAIN

View file

@ -1,6 +1,6 @@
"""Tests for the Bond button device.""" """Tests for the Bond button device."""
from bond_api import Action, DeviceType from bond_async import Action, DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.bond.button import STEP_SIZE from homeassistant.components.bond.button import STEP_SIZE

View file

@ -1,7 +1,7 @@
"""Tests for the Bond cover device.""" """Tests for the Bond cover device."""
from datetime import timedelta from datetime import timedelta
from bond_api import Action, DeviceType from bond_async import Action, DeviceType
from homeassistant import core from homeassistant import core
from homeassistant.components.cover import ( from homeassistant.components.cover import (

View file

@ -3,7 +3,8 @@ import asyncio
from datetime import timedelta from datetime import timedelta
from unittest.mock import patch from unittest.mock import patch
from bond_api import BPUPSubscriptions, DeviceType from bond_async import BPUPSubscriptions, DeviceType
from bond_async.bpup import BPUP_ALIVE_TIMEOUT
from homeassistant import core from homeassistant import core
from homeassistant.components import fan from homeassistant.components import fan
@ -44,24 +45,47 @@ async def test_bpup_goes_offline_and_recovers_same_entity(hass: core.HomeAssista
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/test-device-id/update", "t": "devices/test-device-id/state",
"b": {"power": 1, "speed": 3, "direction": 0}, "b": {"power": 1, "speed": 3, "direction": 0},
} }
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 100 assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 100
# Send a message for the wrong device to make sure its ignored
# we should never get this callback
bpup_subs.notify(
{
"s": 200,
"t": "devices/other-device-id/state",
"b": {"power": 1, "speed": 1, "direction": 0},
}
)
await hass.async_block_till_done()
assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 100
# Test we ignore messages for the wrong topic
bpup_subs.notify(
{
"s": 200,
"t": "devices/test-device-id/other_topic",
"b": {"power": 1, "speed": 1, "direction": 0},
}
)
await hass.async_block_till_done()
assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 100
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/test-device-id/update", "t": "devices/test-device-id/state",
"b": {"power": 1, "speed": 1, "direction": 0}, "b": {"power": 1, "speed": 1, "direction": 0},
} }
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 33 assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 33
bpup_subs.last_message_time = 0 bpup_subs.last_message_time = -BPUP_ALIVE_TIMEOUT
with patch_bond_device_state(side_effect=asyncio.TimeoutError): with patch_bond_device_state(side_effect=asyncio.TimeoutError):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=230)) async_fire_time_changed(hass, utcnow() + timedelta(seconds=230))
await hass.async_block_till_done() await hass.async_block_till_done()
@ -75,7 +99,7 @@ async def test_bpup_goes_offline_and_recovers_same_entity(hass: core.HomeAssista
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/test-device-id/update", "t": "devices/test-device-id/state",
"b": {"power": 1, "speed": 2, "direction": 0}, "b": {"power": 1, "speed": 2, "direction": 0},
} }
) )
@ -106,7 +130,7 @@ async def test_bpup_goes_offline_and_recovers_different_entity(
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/test-device-id/update", "t": "devices/test-device-id/state",
"b": {"power": 1, "speed": 3, "direction": 0}, "b": {"power": 1, "speed": 3, "direction": 0},
} }
) )
@ -116,14 +140,14 @@ async def test_bpup_goes_offline_and_recovers_different_entity(
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/test-device-id/update", "t": "devices/test-device-id/state",
"b": {"power": 1, "speed": 1, "direction": 0}, "b": {"power": 1, "speed": 1, "direction": 0},
} }
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 33 assert hass.states.get("fan.name_1").attributes[fan.ATTR_PERCENTAGE] == 33
bpup_subs.last_message_time = 0 bpup_subs.last_message_time = -BPUP_ALIVE_TIMEOUT
with patch_bond_device_state(side_effect=asyncio.TimeoutError): with patch_bond_device_state(side_effect=asyncio.TimeoutError):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=230)) async_fire_time_changed(hass, utcnow() + timedelta(seconds=230))
await hass.async_block_till_done() await hass.async_block_till_done()
@ -133,7 +157,7 @@ async def test_bpup_goes_offline_and_recovers_different_entity(
bpup_subs.notify( bpup_subs.notify(
{ {
"s": 200, "s": 200,
"t": "bond/not-this-device-id/update", "t": "devices/not-this-device-id/state",
"b": {"power": 1, "speed": 2, "direction": 0}, "b": {"power": 1, "speed": 2, "direction": 0},
} }
) )

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from unittest.mock import call from unittest.mock import call
from bond_api import Action, DeviceType, Direction from bond_async import Action, DeviceType, Direction
import pytest import pytest
from homeassistant import core from homeassistant import core

View file

@ -3,7 +3,7 @@ import asyncio
from unittest.mock import MagicMock, Mock from unittest.mock import MagicMock, Mock
from aiohttp import ClientConnectionError, ClientResponseError from aiohttp import ClientConnectionError, ClientResponseError
from bond_api import DeviceType from bond_async import DeviceType
import pytest import pytest
from homeassistant.components.bond.const import DOMAIN from homeassistant.components.bond.const import DOMAIN

View file

@ -1,7 +1,7 @@
"""Tests for the Bond light device.""" """Tests for the Bond light device."""
from datetime import timedelta from datetime import timedelta
from bond_api import Action, DeviceType from bond_async import Action, DeviceType
import pytest import pytest
from homeassistant import core from homeassistant import core

View file

@ -1,7 +1,7 @@
"""Tests for the Bond switch device.""" """Tests for the Bond switch device."""
from datetime import timedelta from datetime import timedelta
from bond_api import Action, DeviceType from bond_async import Action, DeviceType
import pytest import pytest
from homeassistant import core from homeassistant import core