Gree update device ips when changed (#57876)

This commit is contained in:
Clifford Roche 2021-12-03 14:18:53 -05:00 committed by GitHub
parent 788a9bd9f7
commit d6c27809dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 19 deletions

View File

@ -103,3 +103,10 @@ class DiscoveryService(Listener):
await coordo.async_refresh()
async_dispatcher_send(self.hass, DISPATCH_DEVICE_DISCOVERED, coordo)
async def device_update(self, device_info: DeviceInfo) -> None:
"""Handle updates in device information, update if ip has changed."""
for coordinator in self.hass.data[DOMAIN][COORDINATORS]:
if coordinator.device.device_info.mac == device_info.mac:
coordinator.device.device_info.ip = device_info.ip
await coordinator.async_refresh()

View File

@ -5,7 +5,10 @@ from unittest.mock import AsyncMock, Mock
from greeclimate.discovery import Listener
from homeassistant.components.gree.const import DISCOVERY_TIMEOUT
from homeassistant.components.gree.const import DISCOVERY_TIMEOUT, DOMAIN as GREE_DOMAIN
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
_LOGGER = logging.getLogger(__name__)
@ -16,6 +19,7 @@ class FakeDiscovery:
def __init__(self, timeout: int = DISCOVERY_TIMEOUT) -> None:
"""Initialize the class."""
self.mock_devices = [build_device_mock()]
self.last_mock_infos = []
self.timeout = timeout
self._listeners = []
self.scan_count = 0
@ -29,14 +33,27 @@ class FakeDiscovery:
self.scan_count += 1
_LOGGER.info("CALLED SCAN %d TIMES", self.scan_count)
infos = [x.device_info for x in self.mock_devices]
mock_infos = [x.device_info for x in self.mock_devices]
new_infos = []
updated_infos = []
for info in mock_infos:
if not [i for i in self.last_mock_infos if info.mac == i.mac]:
new_infos.append(info)
else:
last_info = next(i for i in self.last_mock_infos if info.mac == i.mac)
if info.ip != last_info.ip:
updated_infos.append(info)
self.last_mock_infos = mock_infos
for listener in self._listeners:
[await listener.device_found(x) for x in infos]
[await listener.device_found(x) for x in new_infos]
[await listener.device_update(x) for x in updated_infos]
if wait_for:
await asyncio.sleep(wait_for)
return infos
return new_infos
def build_device_info_mock(
@ -71,3 +88,10 @@ def build_device_mock(name="fake-device-1", ipAddress="1.1.1.1", mac="aabbcc1122
steady_heat=False,
)
return mock
async def async_setup_gree(hass):
"""Set up the gree platform."""
MockConfigEntry(domain=GREE_DOMAIN).add_to_hass(hass)
await async_setup_component(hass, GREE_DOMAIN, {GREE_DOMAIN: {"climate": {}}})
await hass.async_block_till_done()

View File

@ -0,0 +1,67 @@
"""Tests for gree component."""
from datetime import timedelta
from unittest.mock import patch
import pytest
from homeassistant.components.climate.const import DOMAIN
from homeassistant.components.gree.const import COORDINATORS, DOMAIN as GREE
import homeassistant.util.dt as dt_util
from .common import async_setup_gree, build_device_mock
from tests.common import async_fire_time_changed
ENTITY_ID_1 = f"{DOMAIN}.fake_device_1"
ENTITY_ID_2 = f"{DOMAIN}.fake_device_2"
@pytest.fixture
def mock_now():
"""Fixture for dtutil.now."""
return dt_util.utcnow()
async def test_discovery_after_setup(hass, discovery, device, mock_now):
"""Test gree devices don't change after multiple discoveries."""
mock_device_1 = build_device_mock(
name="fake-device-1", ipAddress="1.1.1.1", mac="aabbcc112233"
)
mock_device_2 = build_device_mock(
name="fake-device-2", ipAddress="2.2.2.2", mac="bbccdd223344"
)
discovery.return_value.mock_devices = [mock_device_1, mock_device_2]
device.side_effect = [mock_device_1, mock_device_2]
await async_setup_gree(hass)
await hass.async_block_till_done()
assert discovery.return_value.scan_count == 1
assert len(hass.states.async_all(DOMAIN)) == 2
device_infos = [x.device.device_info for x in hass.data[GREE][COORDINATORS]]
assert device_infos[0].ip == "1.1.1.1"
assert device_infos[1].ip == "2.2.2.2"
# rediscover the same devices with new ip addresses should update
mock_device_1 = build_device_mock(
name="fake-device-1", ipAddress="1.1.1.2", mac="aabbcc112233"
)
mock_device_2 = build_device_mock(
name="fake-device-2", ipAddress="2.2.2.1", mac="bbccdd223344"
)
discovery.return_value.mock_devices = [mock_device_1, mock_device_2]
device.side_effect = [mock_device_1, mock_device_2]
next_update = mock_now + timedelta(minutes=6)
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
async_fire_time_changed(hass, next_update)
await hass.async_block_till_done()
assert discovery.return_value.scan_count == 2
assert len(hass.states.async_all(DOMAIN)) == 2
device_infos = [x.device.device_info for x in hass.data[GREE][COORDINATORS]]
assert device_infos[0].ip == "1.1.1.2"
assert device_infos[1].ip == "2.2.2.1"

View File

@ -43,11 +43,7 @@ from homeassistant.components.gree.climate import (
HVAC_MODES_REVERSE,
SUPPORTED_FEATURES,
)
from homeassistant.components.gree.const import (
DOMAIN as GREE_DOMAIN,
FAN_MEDIUM_HIGH,
FAN_MEDIUM_LOW,
)
from homeassistant.components.gree.const import FAN_MEDIUM_HIGH, FAN_MEDIUM_LOW
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_FRIENDLY_NAME,
@ -59,12 +55,11 @@ from homeassistant.const import (
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from .common import build_device_mock
from .common import async_setup_gree, build_device_mock
from tests.common import MockConfigEntry, async_fire_time_changed
from tests.common import async_fire_time_changed
ENTITY_ID = f"{DOMAIN}.fake_device_1"
@ -75,13 +70,6 @@ def mock_now():
return dt_util.utcnow()
async def async_setup_gree(hass):
"""Set up the gree platform."""
MockConfigEntry(domain=GREE_DOMAIN).add_to_hass(hass)
await async_setup_component(hass, GREE_DOMAIN, {GREE_DOMAIN: {"climate": {}}})
await hass.async_block_till_done()
async def test_discovery_called_once(hass, discovery, device):
"""Test discovery is only ever called once."""
await async_setup_gree(hass)