1 """Support for Tuya Smart devices."""
3 from __future__
import annotations
6 from typing
import Any, NamedTuple
8 from tuya_sharing
import (
11 SharingDeviceListener,
32 TUYA_HA_SIGNAL_UPDATE_ENTITY,
36 logging.getLogger(
"tuya_sharing").setLevel(logging.CRITICAL)
38 type TuyaConfigEntry = ConfigEntry[HomeAssistantTuyaData]
42 """Tuya data stored in the Home Assistant data object."""
45 listener: SharingDeviceListener
49 """Async setup hass config entry."""
50 if CONF_APP_TYPE
in entry.data:
56 entry.data[CONF_USER_CODE],
57 entry.data[CONF_TERMINAL_ID],
58 entry.data[CONF_ENDPOINT],
59 entry.data[CONF_TOKEN_INFO],
64 manager.add_device_listener(listener)
68 await hass.async_add_executor_job(manager.update_device_cache)
69 except Exception
as exc:
72 if "sign invalid" in str(exc):
73 msg =
"Authentication failed. Please re-authenticate"
84 device_registry = dr.async_get(hass)
85 for device
in manager.device_map.values():
86 device_registry.async_get_or_create(
87 config_entry_id=entry.entry_id,
88 identifiers={(DOMAIN, device.id)},
91 model=f
"{device.product_name} (unsupported)",
92 model_id=device.product_id,
95 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
98 await hass.async_add_executor_job(manager.refresh_mq)
103 """Remove deleted device registry entry if there are no remaining entities."""
104 device_registry = dr.async_get(hass)
105 for dev_id, device_entry
in list(device_registry.devices.items()):
106 for item
in device_entry.identifiers:
107 if item[0] == DOMAIN
and item[1]
not in device_manager.device_map:
108 device_registry.async_remove_device(dev_id)
113 """Unloading the Tuya platforms."""
114 if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
115 tuya = entry.runtime_data
116 if tuya.manager.mq
is not None:
117 tuya.manager.mq.stop()
118 tuya.manager.remove_device_listener(tuya.listener)
123 """Remove a config entry.
125 This will revoke the credentials from Tuya.
129 entry.data[CONF_USER_CODE],
130 entry.data[CONF_TERMINAL_ID],
131 entry.data[CONF_ENDPOINT],
132 entry.data[CONF_TOKEN_INFO],
134 await hass.async_add_executor_job(manager.unload)
138 """Device Update Listener."""
145 """Init DeviceListener."""
150 self, device: CustomerDevice, updated_status_properties: list[str] |
None
152 """Update device status."""
154 "Received update for device %s: %s (updated properties: %s)",
156 self.
managermanager.device_map[device.id].status,
157 updated_status_properties,
161 f
"{TUYA_HA_SIGNAL_UPDATE_ENTITY}_{device.id}",
162 updated_status_properties,
166 """Add device added listener."""
173 """Add device removed listener."""
178 """Remove device from Home Assistant."""
179 LOGGER.debug(
"Remove device: %s", device_id)
180 device_registry = dr.async_get(self.
hasshass)
181 device_entry = device_registry.async_get_device(
182 identifiers={(DOMAIN, device_id)}
184 if device_entry
is not None:
185 device_registry.async_remove_device(device_entry.id)
189 """Token listener for upstream token updates."""
194 entry: TuyaConfigEntry,
196 """Init TokenListener."""
201 """Update token info in config entry."""
203 **self.
entryentry.data,
205 "t": token_info[
"t"],
206 "uid": token_info[
"uid"],
207 "expire_time": token_info[
"expire_time"],
208 "access_token": token_info[
"access_token"],
209 "refresh_token": token_info[
"refresh_token"],
215 """Update config entry."""
216 self.
hasshass.config_entries.async_update_entry(self.
entryentry, data=data)
218 self.
hasshass.add_job(async_update_entry)
None update_device(self, CustomerDevice device, list[str]|None updated_status_properties)
None __init__(self, HomeAssistant hass, Manager manager)
None async_remove_device(self, str device_id)
None add_device(self, CustomerDevice device)
None remove_device(self, str device_id)
None update_token(self, dict[str, Any] token_info)
None __init__(self, HomeAssistant hass, TuyaConfigEntry entry)
None async_update_entry(HomeAssistant hass, PhilipsTVConfigEntry entry)
bool async_unload_entry(HomeAssistant hass, TuyaConfigEntry entry)
None async_remove_entry(HomeAssistant hass, TuyaConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, TuyaConfigEntry entry)
None cleanup_device_registry(HomeAssistant hass, Manager device_manager)
None dispatcher_send(HomeAssistant hass, str signal, *Any args)