Fix Tado unique mobile device dispatcher (#107631)

* Add unique home ID device dispatch

* Adding fixture for new setup

* Minor refactor work

* Add check for unlinked to different homes

* If the interface returns an error

* Proper error handling

* Feedback fixes

* Comments for error in client

* Typo

* Update homeassistant/components/tado/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/tado/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update devices fix standard

* Dispatch out of loop

* Update dispatcher

* Clean up

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
pull/107720/head
Erwin Douna 2024-01-10 12:09:10 +01:00 committed by GitHub
parent 093e35f4d4
commit 15e3af72d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 14 deletions

View File

@ -186,12 +186,13 @@ class TadoConnector:
def get_mobile_devices(self):
"""Return the Tado mobile devices."""
return self.tado.getMobileDevices()
return self.tado.get_mobile_devices()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Update the registered zones."""
self.update_devices()
self.update_mobile_devices()
self.update_zones()
self.update_home()
@ -203,17 +204,31 @@ class TadoConnector:
_LOGGER.error("Unable to connect to Tado while updating mobile devices")
return
if not mobile_devices:
_LOGGER.debug("No linked mobile devices found for home ID %s", self.home_id)
return
# Errors are planned to be converted to exceptions
# in PyTado library, so this can be removed
if "errors" in mobile_devices and mobile_devices["errors"]:
_LOGGER.error(
"Error for home ID %s while updating mobile devices: %s",
self.home_id,
mobile_devices["errors"],
)
return
for mobile_device in mobile_devices:
self.data["mobile_device"][mobile_device["id"]] = mobile_device
_LOGGER.debug(
"Dispatching update to %s mobile device: %s",
self.home_id,
mobile_device,
)
_LOGGER.debug(
"Dispatching update to %s mobile devices: %s",
self.home_id,
mobile_devices,
)
dispatcher_send(
self.hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED.format(self.home_id),
)
def update_devices(self):
@ -224,6 +239,20 @@ class TadoConnector:
_LOGGER.error("Unable to connect to Tado while updating devices")
return
if not devices:
_LOGGER.debug("No linked devices found for home ID %s", self.home_id)
return
# Errors are planned to be converted to exceptions
# in PyTado library, so this can be removed
if "errors" in devices and devices["errors"]:
_LOGGER.error(
"Error for home ID %s while updating devices: %s",
self.home_id,
devices["errors"],
)
return
for device in devices:
device_short_serial_no = device["shortSerialNo"]
_LOGGER.debug("Updating device %s", device_short_serial_no)

View File

@ -179,7 +179,7 @@ TADO_TO_HA_SWING_MODE_MAP = {
DOMAIN = "tado"
SIGNAL_TADO_UPDATE_RECEIVED = "tado_update_received_{}_{}_{}"
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED = "tado_mobile_device_update_received"
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED = "tado_mobile_device_update_received_{}"
UNIQUE_ID = "unique_id"
DEFAULT_NAME = "Tado"

View File

@ -2,7 +2,6 @@
from __future__ import annotations
import logging
from typing import Any
import voluptuous as vol
@ -22,6 +21,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType
from . import TadoConnector
from .const import CONF_HOME_ID, DATA, DOMAIN, SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED
_LOGGER = logging.getLogger(__name__)
@ -90,7 +90,7 @@ async def async_setup_entry(
entry.async_on_unload(
async_dispatcher_connect(
hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED.format(tado.home_id),
update_devices,
)
)
@ -99,12 +99,12 @@ async def async_setup_entry(
@callback
def add_tracked_entities(
hass: HomeAssistant,
tado: Any,
tado: TadoConnector,
async_add_entities: AddEntitiesCallback,
tracked: set[str],
) -> None:
"""Add new tracker entities from Tado."""
_LOGGER.debug("Fetching Tado devices from API")
_LOGGER.debug("Fetching Tado devices from API for (newly) tracked entities")
new_tracked = []
for device_key, device in tado.data["mobile_device"].items():
if device_key in tracked:
@ -129,7 +129,7 @@ class TadoDeviceTrackerEntity(TrackerEntity):
self,
device_id: str,
device_name: str,
tado: Any,
tado: TadoConnector,
) -> None:
"""Initialize a Tado Device Tracker entity."""
super().__init__()
@ -181,7 +181,7 @@ class TadoDeviceTrackerEntity(TrackerEntity):
self.async_on_remove(
async_dispatcher_connect(
self.hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED.format(self._tado.home_id),
self.on_demand_update,
)
)

View File

@ -0,0 +1,26 @@
[
{
"name": "Home",
"id": 123456,
"settings": {
"geoTrackingEnabled": false,
"specialOffersEnabled": false,
"onDemandLogRetrievalEnabled": false,
"pushNotifications": {
"lowBatteryReminder": true,
"awayModeReminder": true,
"homeModeReminder": true,
"openWindowReminder": true,
"energySavingsReportReminder": true,
"incidentDetection": true,
"energyIqReminder": false
}
},
"deviceMetadata": {
"platform": "Android",
"osVersion": "14",
"model": "Samsung",
"locale": "nl"
}
}
]

View File

@ -17,6 +17,7 @@ async def async_init_integration(
token_fixture = "tado/token.json"
devices_fixture = "tado/devices.json"
mobile_devices_fixture = "tado/mobile_devices.json"
me_fixture = "tado/me.json"
weather_fixture = "tado/weather.json"
home_state_fixture = "tado/home_state.json"
@ -70,6 +71,10 @@ async def async_init_integration(
"https://my.tado.com/api/v2/homes/1/devices",
text=load_fixture(devices_fixture),
)
m.get(
"https://my.tado.com/api/v2/homes/1/mobileDevices",
text=load_fixture(mobile_devices_fixture),
)
m.get(
"https://my.tado.com/api/v2/devices/WR1/",
text=load_fixture(device_wr1_fixture),