Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Tado unique mobile device dispatcher #107631

Merged
53 changes: 43 additions & 10 deletions homeassistant/components/tado/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
INSIDE_TEMPERATURE_MEASUREMENT,
PRESET_AUTO,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICES_UPDATE,
SIGNAL_TADO_UPDATE_RECEIVED,
TEMP_OFFSET,
UPDATE_LISTENER,
Expand Down Expand Up @@ -161,6 +162,7 @@ def __init__(self, hass, username, password, fallback):
self.tado = None
self.zones = None
self.devices = None
self.mobile_devices = None
self.data = {
"device": {},
"mobile_device": {},
Expand All @@ -180,18 +182,20 @@ def setup(self):
# Load zones and devices
self.zones = self.tado.get_zones()
self.devices = self.tado.get_devices()
self.mobile_devices = self.tado.get_mobile_devices()
erwindouna marked this conversation as resolved.
Show resolved Hide resolved
tado_home = self.tado.get_me()["homes"][0]
self.home_id = tado_home["id"]
self.home_name = tado_home["name"]

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()
erwindouna marked this conversation as resolved.
Show resolved Hide resolved
self.update_zones()
self.update_home()

Expand All @@ -203,18 +207,35 @@ def update_mobile_devices(self) -> None:
_LOGGER.error("Unable to connect to Tado while updating mobile devices")
return

if len(mobile_devices) == 0:
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
_LOGGER.warning(
erwindouna marked this conversation as resolved.
Show resolved Hide resolved
"No linked mobile devices found for home ID %s", self.home_id
)
return

if "errors" in mobile_devices and len(mobile_devices["errors"]) > 0:
erwindouna marked this conversation as resolved.
Show resolved Hide resolved
erwindouna marked this conversation as resolved.
Show resolved Hide resolved
_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,
)
dispatcher_send(
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
self.hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED.format(
self.home_id, mobile_device["id"]
),
)

_LOGGER.debug(
"Dispatching update to %s mobile devices: %s",
self.home_id,
mobile_devices,
)
dispatcher_send(
self.hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
)
dispatcher_send(self.hass, SIGNAL_TADO_MOBILE_DEVICES_UPDATE)

def update_devices(self):
"""Update the device data from Tado."""
Expand All @@ -224,6 +245,18 @@ def update_devices(self):
_LOGGER.error("Unable to connect to Tado while updating devices")
return

if len(devices) == 0:
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
_LOGGER.warning("No linked devices found for home ID %s", self.home_id)
return

if "errors" in devices and len(devices["errors"]) > 0:
_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)
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/tado/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@
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_{}_{}"
SIGNAL_TADO_MOBILE_DEVICES_UPDATE = "tao_mobile_devices_update"
UNIQUE_ID = "unique_id"

DEFAULT_NAME = "Tado"
Expand Down
22 changes: 15 additions & 7 deletions homeassistant/components/tado/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from __future__ import annotations

import logging
from typing import Any

import voluptuous as vol

Expand All @@ -22,7 +21,14 @@
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType

from .const import CONF_HOME_ID, DATA, DOMAIN, SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED
from . import TadoConnector
from .const import (
CONF_HOME_ID,
DATA,
DOMAIN,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICES_UPDATE,
)

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -90,7 +96,7 @@ def update_devices() -> None:
entry.async_on_unload(
async_dispatcher_connect(
hass,
SIGNAL_TADO_MOBILE_DEVICE_UPDATE_RECEIVED,
SIGNAL_TADO_MOBILE_DEVICES_UPDATE,
update_devices,
)
)
Expand All @@ -99,12 +105,12 @@ def update_devices() -> None:
@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:
Expand All @@ -128,7 +134,7 @@ def __init__(
self,
device_id: str,
device_name: str,
tado: Any,
tado: TadoConnector,
) -> None:
"""Initialize a Tado Device Tracker entity."""
super().__init__()
Expand Down Expand Up @@ -169,7 +175,9 @@ async def async_added_to_hass(self) -> None:
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._device_id
),
self.on_demand_update,
)
)
Expand Down
26 changes: 26 additions & 0 deletions tests/components/tado/fixtures/mobile_devices.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
]
5 changes: 5 additions & 0 deletions tests/components/tado/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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),
Expand Down