diff --git a/custom_components/localtuya/coordinator.py b/custom_components/localtuya/coordinator.py index 88c0c031..c61c9fc6 100644 --- a/custom_components/localtuya/coordinator.py +++ b/custom_components/localtuya/coordinator.py @@ -84,9 +84,8 @@ def __init__( if reset_dps := self._device_config.reset_dps: self._default_reset_dpids = [int(id.strip()) for id in reset_dps.split(",")] - self.set_logger( - _LOGGER, self._device_config.id, self._device_config.enable_debug - ) + dev = self._device_config + self.set_logger(_LOGGER, dev.id, dev.enable_debug, dev.name) # This has to be done in case the device type is type_0d for entity in self._device_config.entities: @@ -164,7 +163,7 @@ async def _make_connection(self): retry = 0 update_localkey = False - self.debug(f"Trying to connect to {name} - {host}...", force=True) + self.debug(f"Trying to connect to: {host}...", force=True) while retry < self._connect_max_tries: retry += 1 try: @@ -174,7 +173,7 @@ async def _make_connection(self): return await self.abort_connect() self._interface = gateway._interface if self._device_config.enable_debug: - self._interface.enable_debug(True) + self._interface.enable_debug(True, gateway._device_config.name) else: self._interface = await pytuya.connect( self._device_config.host, @@ -184,6 +183,7 @@ async def _make_connection(self): self._device_config.enable_debug, self, ) + self._interface.enable_debug(self._device_config.enable_debug, name) self._interface.add_dps_to_request(self.dps_to_request) break # Succeed break while loop except Exception as ex: # pylint: disable=broad-except @@ -255,7 +255,7 @@ def _new_entity_handler(entity_id): self._connect_task = None self._quick_retry = False - self.debug(f"Success: connected to {name} - {host}", force=True) + self.debug(f"Success: connected to: {host}", force=True) if self.sub_devices: for subdevice in self.sub_devices.values(): @@ -309,12 +309,11 @@ async def close(self): if self._interface is not None: await self._interface.close() self._interface = None - self.debug(f"Closed connection with {self._device_config.name}", force=True) + self.debug(f"Closed connection", force=True) async def update_local_key(self): """Retrieve updated local_key from Cloud API and update the config_entry.""" dev_id = self._device_config.id - name = self._device_config.name cloud_api = self._hass_entry.cloud_data await cloud_api.async_get_devices_list() @@ -338,22 +337,20 @@ async def update_local_key(self): # Update Gateway ID and IP if new_gw := get_gateway_by_deviceid(dev_id, cloud_devs): - self.info(f"Updated {name} gateway ID to: {new_gw.id}") + self.info(f"Gateway ID has been updated to: {new_gw.id}") new_data[CONF_DEVICES][dev_id][CONF_GATEWAY_ID] = new_gw.id if discovery and (local_gw := discovery.devices.get(new_gw.id)): new_ip = local_gw.get(CONF_TUYA_IP, self._device_config.host) new_data[CONF_DEVICES][dev_id][CONF_HOST] = new_ip - self.info(f"Updated {name} IP to: {new_ip}") - - self.info(f"Updated informations for sub-device {name}.") + self.info(f"IP has been updated to: {new_ip}") new_data[CONF_DEVICES][dev_id][CONF_LOCAL_KEY] = self._local_key new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000)) self._hass.config_entries.async_update_entry( self._config_entry, data=new_data ) - self.info(f"local_key updated for device {name}.") + self.info(f"Local-key has been updated") async def set_status(self): """Send self._pending_status payload to device.""" @@ -436,10 +433,12 @@ def fire_event(event, data: dict): def _shutdown_entities(self, now=None): """Shutdown device entities""" - if self.is_sleep: - return - if not self.connected: - self.debug(f"Disconnected: waiting for discovery broadcast", force=True) + if self.is_subdevice: + self.warning(f"Sub-device disconnected from: {self._device_config.host}") + else: + self.warning(f"Disconnected: waiting for discovery broadcast") + + if not self.connected and not self.is_sleep: signal = f"localtuya_{self._device_config.id}" async_dispatcher_send(self._hass, signal, None) @@ -476,6 +475,7 @@ def disconnected(self): asyncio.run_coroutine_threadsafe(self.async_connect(), self._hass.loop) if not self._is_closing: + delay = (0 if self.is_subdevice else 3) + sleep_time self._unsub_on_close.append( - async_call_later(self._hass, sleep_time + 3, self._shutdown_entities) + async_call_later(self._hass, delay, self._shutdown_entities) ) diff --git a/custom_components/localtuya/core/pytuya/__init__.py b/custom_components/localtuya/core/pytuya/__init__.py index a4f6fb4e..6c5a7ed0 100644 --- a/custom_components/localtuya/core/pytuya/__init__.py +++ b/custom_components/localtuya/core/pytuya/__init__.py @@ -252,7 +252,12 @@ class TuyaLoggingAdapter(logging.LoggerAdapter): def process(self, msg, kwargs): """Process log point and return output.""" dev_id = self.extra["device_id"] - return f"[{dev_id[0:3]}...{dev_id[-3:]}] {msg}", kwargs + name = self.extra.get("name") + prefix = f"{dev_id[0:3]}...{dev_id[-3:]}" + if name: + return f"[{prefix} - {name}] {msg}", kwargs + + return f"[{prefix}] {msg}", kwargs class ContextualLogger: @@ -266,10 +271,12 @@ def __init__(self): self._reset_warning = int(time.time()) self._last_warning = "" - def set_logger(self, logger, device_id, enable_debug=False): + def set_logger(self, logger, device_id, enable_debug=False, name=None): """Set base logger to use.""" self._enable_debug = enable_debug - self._logger = TuyaLoggingAdapter(logger, {"device_id": device_id}) + self._logger = TuyaLoggingAdapter( + logger, {"device_id": device_id, "name": name} + ) def debug(self, msg, *args, force=False): """Debug level log for device. force will ignore device debug check.""" @@ -1557,10 +1564,10 @@ def deepcopy_dict(_dict: dict): return MessagePayload(command_override, payload) - def enable_debug(self, enable=False): + def enable_debug(self, enable=False, friendly_name=None): """Enable the debug logs for the device.""" - self.set_logger(_LOGGER, self.id, enable) - self.dispatcher.set_logger(_LOGGER, self.id, enable) + self.set_logger(_LOGGER, self.id, enable, friendly_name) + self.dispatcher.set_logger(_LOGGER, self.id, enable, friendly_name) @property def last_command_sent(self): diff --git a/custom_components/localtuya/entity.py b/custom_components/localtuya/entity.py index def12156..6d9e8e20 100644 --- a/custom_components/localtuya/entity.py +++ b/custom_components/localtuya/entity.py @@ -3,7 +3,7 @@ import logging from typing import Any -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, State from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( @@ -135,6 +135,7 @@ def __init__( self._status = {} self._state = None self._last_state = None + self._stored_states: State | None = None self._hass = device._hass # Default value is available to be provided by Platform entities if required @@ -142,9 +143,8 @@ def __init__( """ Restore on connect setting is available to be provided by Platform entities if required""" - self.set_logger( - logger, self._device_config.id, self._device_config.enable_debug - ) + dev = self._device_config + self.set_logger(logger, dev.id, dev.enable_debug, dev.name) self.debug(f"Initialized {self._config.get(CONF_PLATFORM)} [{self.name}]") async def async_added_to_hass(self): @@ -155,6 +155,7 @@ async def async_added_to_hass(self): stored_data = await self.async_get_last_state() if stored_data: + self._stored_states = stored_data self.status_restored(stored_data) def _update_handler(new_status: dict | None):