Obfuscated diagnostics; fixed IP auto-update; cleaned logs

This commit is contained in:
rospogrigio
2022-05-23 12:31:15 +02:00
committed by GitHub Actions
parent cdfe8e4906
commit 6be13c5ba0
7 changed files with 112 additions and 125 deletions

View File

@@ -5,27 +5,26 @@ import time
from datetime import timedelta from datetime import timedelta
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.device_registry import DeviceEntry
import homeassistant.helpers.entity_registry as er import homeassistant.helpers.entity_registry as er
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONF_CLIENT_ID, CONF_CLIENT_ID,
CONF_CLIENT_SECRET, CONF_CLIENT_SECRET,
CONF_REGION,
CONF_DEVICE_ID, CONF_DEVICE_ID,
CONF_DEVICES, CONF_DEVICES,
CONF_ENTITIES, CONF_ENTITIES,
CONF_HOST, CONF_HOST,
CONF_ID, CONF_ID,
CONF_PLATFORM, CONF_PLATFORM,
CONF_REGION,
CONF_USERNAME, CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
SERVICE_RELOAD, SERVICE_RELOAD,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.event import async_track_time_interval
from .cloud_api import TuyaCloudApi from .cloud_api import TuyaCloudApi
@@ -66,7 +65,6 @@ SERVICE_SET_DP_SCHEMA = vol.Schema(
async def async_setup(hass: HomeAssistant, config: dict): async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the LocalTuya integration component.""" """Set up the LocalTuya integration component."""
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})
print("SETUP")
device_cache = {} device_cache = {}
@@ -134,10 +132,11 @@ async def async_setup(hass: HomeAssistant, config: dict):
# settings triggers a reload of the config entry, which tears down the device # settings triggers a reload of the config entry, which tears down the device
# so no need to connect in that case. # so no need to connect in that case.
if updated: if updated:
new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000)) _LOGGER.debug(
hass.config_entries.async_update_entry( "Updating keys for device %s: %s %s", device_id, device_ip, product_key
entry, data=new_data
) )
new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000))
hass.config_entries.async_update_entry(entry, data=new_data)
device = hass.data[DOMAIN][TUYA_DEVICES][device_id] device = hass.data[DOMAIN][TUYA_DEVICES][device_id]
if not device.connected: if not device.connected:
device.async_connect() device.async_connect()
@@ -148,26 +147,17 @@ async def async_setup(hass: HomeAssistant, config: dict):
if not device.connected: if not device.connected:
device.async_connect() device.async_connect()
discovery = TuyaDiscovery(_device_discovered)
def _shutdown(event): def _shutdown(event):
"""Clean up resources when shutting down.""" """Clean up resources when shutting down."""
discovery.close() discovery.close()
try:
await discovery.start()
hass.data[DOMAIN][DATA_DISCOVERY] = discovery
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown)
except Exception: # pylint: disable=broad-except
_LOGGER.exception("failed to set up discovery")
async def _async_reconnect(now): async def _async_reconnect(now):
"""Try connecting to devices not already connected to.""" """Try connecting to devices not already connected to."""
for device_id, device in hass.data[DOMAIN][TUYA_DEVICES].items(): for device_id, device in hass.data[DOMAIN][TUYA_DEVICES].items():
if not device.connected: if not device.connected:
device.async_connect() device.async_connect()
# async_track_time_interval(hass, _async_reconnect, RECONNECT_INTERVAL) async_track_time_interval(hass, _async_reconnect, RECONNECT_INTERVAL)
hass.helpers.service.async_register_admin_service( hass.helpers.service.async_register_admin_service(
DOMAIN, DOMAIN,
@@ -179,6 +169,14 @@ async def async_setup(hass: HomeAssistant, config: dict):
DOMAIN, SERVICE_SET_DP, _handle_set_dp, schema=SERVICE_SET_DP_SCHEMA DOMAIN, SERVICE_SET_DP, _handle_set_dp, schema=SERVICE_SET_DP_SCHEMA
) )
discovery = TuyaDiscovery(_device_discovered)
try:
await discovery.start()
hass.data[DOMAIN][DATA_DISCOVERY] = discovery
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown)
except Exception: # pylint: disable=broad-except
_LOGGER.exception("failed to set up discovery")
return True return True
@@ -228,7 +226,6 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
print("SETUP ENTRY STARTED!")
"""Set up LocalTuya integration from a config entry.""" """Set up LocalTuya integration from a config entry."""
unsub_listener = entry.add_update_listener(update_listener) unsub_listener = entry.add_update_listener(update_listener)
hass.data[DOMAIN][UNSUB_LISTENER] = unsub_listener hass.data[DOMAIN][UNSUB_LISTENER] = unsub_listener
@@ -244,19 +241,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
_LOGGER.error("Cloud API connection failed: %s", res) _LOGGER.error("Cloud API connection failed: %s", res)
_LOGGER.info("Cloud API connection succeeded.") _LOGGER.info("Cloud API connection succeeded.")
res = await tuya_api.async_get_devices_list() res = await tuya_api.async_get_devices_list()
for dev_id, dev in tuya_api._device_list.items():
_LOGGER.debug(
"Cloud device: %s \t dev_id %s \t key %s", dev["name"], dev["id"], dev["local_key"]
)
hass.data[DOMAIN][DATA_CLOUD] = tuya_api hass.data[DOMAIN][DATA_CLOUD] = tuya_api
# device = TuyaDevice(hass, entry.data)
#
# hass.data[DOMAIN][entry.entry_id] = {
# UNSUB_LISTENER: unsub_listener,
# TUYA_DEVICE: device,
# }
#
async def setup_entities(dev_id): async def setup_entities(dev_id):
dev_entry = entry.data[CONF_DEVICES][dev_id] dev_entry = entry.data[CONF_DEVICES][dev_id]
device = TuyaDevice(hass, entry, dev_id) device = TuyaDevice(hass, entry, dev_id)
@@ -272,19 +258,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
device.async_connect() device.async_connect()
await async_remove_orphan_entities(hass, entry) await async_remove_orphan_entities(hass, entry)
print("SETUP_ENTITIES for {} ENDED".format(dev_id))
for dev_id in entry.data[CONF_DEVICES]: for dev_id in entry.data[CONF_DEVICES]:
hass.async_create_task(setup_entities(dev_id)) hass.async_create_task(setup_entities(dev_id))
print("SETUP ENTRY ENDED!")
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry.""" """Unload a config entry."""
# print("ASYNC_UNLOAD_ENTRY INVOKED...")
platforms = {} platforms = {}
for dev_id, dev_entry in entry.data[CONF_DEVICES].items(): for dev_id, dev_entry in entry.data[CONF_DEVICES].items():
for entity in dev_entry[CONF_ENTITIES]: for entity in dev_entry[CONF_ENTITIES]:
@@ -301,20 +283,18 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
hass.data[DOMAIN][UNSUB_LISTENER]() hass.data[DOMAIN][UNSUB_LISTENER]()
for dev_id, device in hass.data[DOMAIN][TUYA_DEVICES].items(): for dev_id, device in hass.data[DOMAIN][TUYA_DEVICES].items():
if device.connected:
await device.close() await device.close()
if unload_ok: if unload_ok:
hass.data[DOMAIN][TUYA_DEVICES] = {} hass.data[DOMAIN][TUYA_DEVICES] = {}
# print("ASYNC_UNLOAD_ENTRY ENDED")
return True return True
async def update_listener(hass, config_entry): async def update_listener(hass, config_entry):
"""Update listener.""" """Update listener."""
print("UPDATE_LISTENER INVOKED")
await hass.config_entries.async_reload(config_entry.entry_id) await hass.config_entries.async_reload(config_entry.entry_id)
print("UPDATE_LISTENER RELOADED {}".format(config_entry.entry_id))
async def async_remove_config_entry_device( async def async_remove_config_entry_device(
@@ -323,9 +303,18 @@ async def async_remove_config_entry_device(
"""Remove a config entry from a device.""" """Remove a config entry from a device."""
dev_id = list(device_entry.identifiers)[0][1].split("_")[-1] dev_id = list(device_entry.identifiers)[0][1].split("_")[-1]
ent_reg = await er.async_get_registry(hass)
entities = {
ent.unique_id: ent.entity_id
for ent in er.async_entries_for_config_entry(ent_reg, config_entry.entry_id)
if dev_id in ent.unique_id
}
for entity_id in entities.values():
ent_reg.async_remove(entity_id)
if dev_id not in config_entry.data[CONF_DEVICES]: if dev_id not in config_entry.data[CONF_DEVICES]:
_LOGGER.debug( _LOGGER.info(
"Device ID %s not found in config entry: finalizing device removal", dev_id "Device %s not found in config entry: finalizing device removal", dev_id
) )
return True return True
@@ -340,15 +329,7 @@ async def async_remove_config_entry_device(
data=new_data, data=new_data,
) )
ent_reg = await er.async_get_registry(hass) _LOGGER.info("Device %s removed.", dev_id)
entities = {
ent.unique_id: ent.entity_id
for ent in er.async_entries_for_config_entry(ent_reg, config_entry.entry_id)
if dev_id in ent.unique_id
}
for entity_id in entities.values():
ent_reg.async_remove(entity_id)
print("REMOVED {}".format(entity_id))
return True return True
@@ -361,11 +342,8 @@ async def async_remove_orphan_entities(hass, entry):
ent.unique_id: ent.entity_id ent.unique_id: ent.entity_id
for ent in er.async_entries_for_config_entry(ent_reg, entry.entry_id) for ent in er.async_entries_for_config_entry(ent_reg, entry.entry_id)
} }
print("ENTITIES ORPHAN {}".format(entities)) _LOGGER.info("ENTITIES ORPHAN %s", entities)
return return
res = ent_reg.async_remove("switch.aa")
print("RESULT ORPHAN {}".format(res))
# del entities[101]
for entity in entry.data[CONF_ENTITIES]: for entity in entry.data[CONF_ENTITIES]:
if entity[CONF_ID] in entities: if entity[CONF_ID] in entities:

View File

@@ -11,18 +11,18 @@ from homeassistant.components.climate import (
ClimateEntity, ClimateEntity,
) )
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
HVAC_MODE_AUTO, HVAC_MODE_AUTO,
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
HVAC_MODE_OFF, HVAC_MODE_OFF,
PRESET_AWAY,
PRESET_ECO,
PRESET_HOME,
PRESET_NONE,
SUPPORT_PRESET_MODE, SUPPORT_PRESET_MODE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_RANGE, SUPPORT_TARGET_TEMPERATURE_RANGE,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_HEAT,
PRESET_NONE,
PRESET_ECO,
PRESET_AWAY,
PRESET_HOME,
) )
from homeassistant.const import ( from homeassistant.const import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
@@ -37,21 +37,21 @@ from homeassistant.const import (
from .common import LocalTuyaEntity, async_setup_entry from .common import LocalTuyaEntity, async_setup_entry
from .const import ( from .const import (
CONF_CURRENT_TEMPERATURE_DP, CONF_CURRENT_TEMPERATURE_DP,
CONF_MAX_TEMP_DP, CONF_ECO_DP,
CONF_MIN_TEMP_DP, CONF_ECO_VALUE,
CONF_PRECISION,
CONF_TARGET_PRECISION,
CONF_TARGET_TEMPERATURE_DP,
CONF_TEMPERATURE_STEP,
CONF_HVAC_MODE_DP,
CONF_HVAC_MODE_SET,
CONF_HEURISTIC_ACTION, CONF_HEURISTIC_ACTION,
CONF_HVAC_ACTION_DP, CONF_HVAC_ACTION_DP,
CONF_HVAC_ACTION_SET, CONF_HVAC_ACTION_SET,
CONF_ECO_DP, CONF_HVAC_MODE_DP,
CONF_ECO_VALUE, CONF_HVAC_MODE_SET,
CONF_MAX_TEMP_DP,
CONF_MIN_TEMP_DP,
CONF_PRECISION,
CONF_PRESET_DP, CONF_PRESET_DP,
CONF_PRESET_SET, CONF_PRESET_SET,
CONF_TARGET_PRECISION,
CONF_TARGET_TEMPERATURE_DP,
CONF_TEMPERATURE_STEP,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@@ -3,9 +3,10 @@ import functools
import hashlib import hashlib
import hmac import hmac
import json import json
import requests
import time import time
import requests
# Signature algorithm. # Signature algorithm.
def calc_sign(msg, key): def calc_sign(msg, key):

View File

@@ -1,8 +1,8 @@
"""Code shared between all platforms.""" """Code shared between all platforms."""
import asyncio import asyncio
import logging import logging
from datetime import timedelta
import time import time
from datetime import timedelta
from homeassistant.const import ( from homeassistant.const import (
CONF_DEVICE_ID, CONF_DEVICE_ID,
@@ -16,11 +16,11 @@ from homeassistant.const import (
CONF_SCAN_INTERVAL, CONF_SCAN_INTERVAL,
) )
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_connect,
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from . import pytuya from . import pytuya
@@ -28,8 +28,8 @@ from .const import (
ATTR_UPDATED_AT, ATTR_UPDATED_AT,
CONF_LOCAL_KEY, CONF_LOCAL_KEY,
CONF_PROTOCOL_VERSION, CONF_PROTOCOL_VERSION,
DOMAIN,
DATA_CLOUD, DATA_CLOUD,
DOMAIN,
TUYA_DEVICES, TUYA_DEVICES,
) )
@@ -74,6 +74,10 @@ async def async_setup_entry(
if len(entities_to_setup) > 0: if len(entities_to_setup) > 0:
if dev_id not in hass.data[DOMAIN][TUYA_DEVICES]:
print("STRANO: {}".format(hass.data[DOMAIN][TUYA_DEVICES]))
return
tuyainterface = hass.data[DOMAIN][TUYA_DEVICES][dev_id] tuyainterface = hass.data[DOMAIN][TUYA_DEVICES][dev_id]
dps_config_fields = list(get_dps_for_platform(flow_schema)) dps_config_fields = list(get_dps_for_platform(flow_schema))
@@ -127,7 +131,7 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
super().__init__() super().__init__()
self._hass = hass self._hass = hass
self._config_entry = config_entry self._config_entry = config_entry
self._dev_config_entry = config_entry.data[CONF_DEVICES][dev_id] self._dev_config_entry = config_entry.data[CONF_DEVICES][dev_id].copy()
self._interface = None self._interface = None
self._status = {} self._status = {}
self.dps_to_request = {} self.dps_to_request = {}
@@ -205,9 +209,7 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
except Exception as e: # pylint: disable=broad-except except Exception as e: # pylint: disable=broad-except
self.exception(f"Connect to {self._dev_config_entry[CONF_HOST]} failed") self.exception(f"Connect to {self._dev_config_entry[CONF_HOST]} failed")
self.error("BBBB: %s", type(type(e))) if "json.decode" in str(type(e)):
if 'json.decode' in str(type(e)):
self.error("BBBB2")
await self.update_local_key() await self.update_local_key()
if self._interface is not None: if self._interface is not None:
@@ -220,7 +222,6 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
await self._hass.data[DOMAIN][DATA_CLOUD].async_get_devices_list() await self._hass.data[DOMAIN][DATA_CLOUD].async_get_devices_list()
cloud_devs = self._hass.data[DOMAIN][DATA_CLOUD]._device_list cloud_devs = self._hass.data[DOMAIN][DATA_CLOUD]._device_list
if dev_id in cloud_devs: if dev_id in cloud_devs:
old_key = self._local_key
self._local_key = cloud_devs[dev_id].get(CONF_LOCAL_KEY) self._local_key = cloud_devs[dev_id].get(CONF_LOCAL_KEY)
new_data = self._config_entry.data.copy() new_data = self._config_entry.data.copy()
new_data[CONF_DEVICES][dev_id][CONF_LOCAL_KEY] = self._local_key new_data[CONF_DEVICES][dev_id][CONF_LOCAL_KEY] = self._local_key
@@ -229,10 +230,7 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
self._config_entry, self._config_entry,
data=new_data, data=new_data,
) )
self.debug( self.info("local_key updated for device %s.", dev_id)
"New local key for %s: from %s to %s",
dev_id, old_key, self._local_key
)
async def _async_refresh(self, _now): async def _async_refresh(self, _now):
if self._interface is not None: if self._interface is not None:
@@ -250,7 +248,7 @@ class TuyaDevice(pytuya.TuyaListener, pytuya.ContextualLogger):
self._disconnect_task() self._disconnect_task()
self.debug( self.debug(
"Closed connection with device %s.", "Closed connection with device %s.",
self._dev_config_entry[CONF_FRIENDLY_NAME] self._dev_config_entry[CONF_FRIENDLY_NAME],
) )
async def set_dp(self, state, dp_index): async def set_dp(self, state, dp_index):

View File

@@ -9,6 +9,8 @@ import homeassistant.helpers.entity_registry as er
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries, core, exceptions from homeassistant import config_entries, core, exceptions
from homeassistant.const import ( from homeassistant.const import (
CONF_CLIENT_ID,
CONF_CLIENT_SECRET,
CONF_DEVICE_ID, CONF_DEVICE_ID,
CONF_DEVICES, CONF_DEVICES,
CONF_ENTITIES, CONF_ENTITIES,
@@ -18,29 +20,27 @@ from homeassistant.const import (
CONF_MODEL, CONF_MODEL,
CONF_NAME, CONF_NAME,
CONF_PLATFORM, CONF_PLATFORM,
CONF_SCAN_INTERVAL,
CONF_CLIENT_ID,
CONF_CLIENT_SECRET,
CONF_REGION, CONF_REGION,
CONF_SCAN_INTERVAL,
CONF_USERNAME, CONF_USERNAME,
) )
from homeassistant.core import callback from homeassistant.core import callback
from .cloud_api import TuyaCloudApi from .cloud_api import TuyaCloudApi
from .common import async_config_entry_by_device_id, pytuya from .common import pytuya
from .const import ( from .const import (
ATTR_UPDATED_AT,
CONF_ACTION, CONF_ACTION,
CONF_ADD_DEVICE, CONF_ADD_DEVICE,
CONF_DPS_STRINGS,
CONF_EDIT_DEVICE, CONF_EDIT_DEVICE,
CONF_SETUP_CLOUD,
CONF_LOCAL_KEY, CONF_LOCAL_KEY,
CONF_PRODUCT_NAME, CONF_PRODUCT_NAME,
CONF_PROTOCOL_VERSION, CONF_PROTOCOL_VERSION,
CONF_SETUP_CLOUD,
CONF_USER_ID, CONF_USER_ID,
CONF_DPS_STRINGS,
ATTR_UPDATED_AT,
DATA_DISCOVERY,
DATA_CLOUD, DATA_CLOUD,
DATA_DISCOVERY,
DOMAIN, DOMAIN,
PLATFORMS, PLATFORMS,
) )
@@ -304,11 +304,6 @@ class LocaltuyaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
placeholders = {"msg": res["msg"]} placeholders = {"msg": res["msg"]}
defaults = {} defaults = {}
defaults[CONF_REGION] = "eu"
defaults[CONF_CLIENT_ID] = "xxx"
defaults[CONF_CLIENT_SECRET] = "xxx"
defaults[CONF_USER_ID] = "xxx"
defaults[CONF_USERNAME] = "xxx"
defaults.update(user_input or {}) defaults.update(user_input or {})
return self.async_show_form( return self.async_show_form(
@@ -383,16 +378,17 @@ class LocalTuyaOptionsFlowHandler(config_entries.OptionsFlow):
cloud_devs = cloud_api._device_list cloud_devs = cloud_api._device_list
for dev_id, dev in new_data[CONF_DEVICES].items(): for dev_id, dev in new_data[CONF_DEVICES].items():
if CONF_MODEL not in dev and dev_id in cloud_devs: if CONF_MODEL not in dev and dev_id in cloud_devs:
new_data[CONF_DEVICES][dev_id][CONF_MODEL] = cloud_devs[dev_id].get( model = cloud_devs[dev_id].get(CONF_PRODUCT_NAME)
CONF_PRODUCT_NAME new_data[CONF_DEVICES][dev_id][CONF_MODEL] = model
)
new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000)) new_data[ATTR_UPDATED_AT] = str(int(time.time() * 1000))
self.hass.config_entries.async_update_entry( self.hass.config_entries.async_update_entry(
self.config_entry, self.config_entry,
data=new_data, data=new_data,
) )
return self.async_create_entry(title=new_data.get(CONF_USERNAME), data={}) return self.async_create_entry(
title=new_data.get(CONF_USERNAME), data={}
)
errors["base"] = res["reason"] errors["base"] = res["reason"]
placeholders = {"msg": res["msg"]} placeholders = {"msg": res["msg"]}
@@ -559,7 +555,6 @@ class LocalTuyaOptionsFlowHandler(config_entries.OptionsFlow):
CONF_ENTITIES: self.entities, CONF_ENTITIES: self.entities,
} }
# entry = async_config_entry_by_device_id(self.hass, self.unique_id)
dev_id = self.device_data.get(CONF_DEVICE_ID) dev_id = self.device_data.get(CONF_DEVICE_ID)
if dev_id in self.config_entry.data[CONF_DEVICES]: if dev_id in self.config_entry.data[CONF_DEVICES]:
self.hass.config_entries.async_update_entry( self.hass.config_entries.async_update_entry(

View File

@@ -1,13 +1,18 @@
"""Diagnostics support for LocalTuya.""" """Diagnostics support for LocalTuya."""
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DEVICES from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_DEVICES
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntry from homeassistant.helpers.device_registry import DeviceEntry
from .const import DOMAIN, DATA_CLOUD from .const import CONF_LOCAL_KEY, CONF_USER_ID, DATA_CLOUD, DOMAIN
CLOUD_DEVICES = "cloud_devices"
DEVICE_CONFIG = "device_config"
DEVICE_CLOUD_INFO = "device_cloud_info"
async def async_get_config_entry_diagnostics( async def async_get_config_entry_diagnostics(
@@ -15,14 +20,20 @@ async def async_get_config_entry_diagnostics(
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
data = {} data = {}
data = {**entry.data} data = entry.data.copy()
# print("DATA is {}".format(data))
tuya_api = hass.data[DOMAIN][DATA_CLOUD] tuya_api = hass.data[DOMAIN][DATA_CLOUD]
data["cloud_devices"] = tuya_api._device_list
# censoring private information # censoring private information
# data["token"] = re.sub(r"[^\-]", "*", data["token"]) for field in [CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_USER_ID]:
# data["userId"] = re.sub(r"[^\-]", "*", data["userId"]) data[field] = f"{data[field][0:3]}...{data[field][-3:]}"
for dev_id, dev in data[CONF_DEVICES].items():
local_key = data[CONF_DEVICES][dev_id][CONF_LOCAL_KEY]
local_key_obfuscated = f"{local_key[0:3]}...{local_key[-3:]}"
data[CONF_DEVICES][dev_id][CONF_LOCAL_KEY] = local_key_obfuscated
data[CLOUD_DEVICES] = tuya_api._device_list
for dev_id, dev in data[CLOUD_DEVICES].items():
local_key = data[CLOUD_DEVICES][dev_id][CONF_LOCAL_KEY]
local_key_obfuscated = f"{local_key[0:3]}...{local_key[-3:]}"
data[CLOUD_DEVICES][dev_id][CONF_LOCAL_KEY] = local_key_obfuscated
return data return data
@@ -32,9 +43,14 @@ async def async_get_device_diagnostics(
"""Return diagnostics for a device entry.""" """Return diagnostics for a device entry."""
data = {} data = {}
dev_id = list(device.identifiers)[0][1].split("_")[-1] dev_id = list(device.identifiers)[0][1].split("_")[-1]
data["device_config"] = entry.data[CONF_DEVICES][dev_id] data[DEVICE_CONFIG] = entry.data[CONF_DEVICES][dev_id]
local_key = data[DEVICE_CONFIG][CONF_LOCAL_KEY]
data[DEVICE_CONFIG][CONF_LOCAL_KEY] = f"{local_key[0:3]}...{local_key[-3:]}"
tuya_api = hass.data[DOMAIN][DATA_CLOUD] tuya_api = hass.data[DOMAIN][DATA_CLOUD]
if dev_id in tuya_api._device_list: if dev_id in tuya_api._device_list:
data["device_cloud_info"] = tuya_api._device_list[dev_id] data[DEVICE_CLOUD_INFO] = tuya_api._device_list[dev_id]
local_key = data[DEVICE_CLOUD_INFO][CONF_LOCAL_KEY]
data[DEVICE_CLOUD_INFO][CONF_LOCAL_KEY] = f"{local_key[0:3]}...{local_key[-3:]}"
# data["log"] = hass.data[DOMAIN][CONF_DEVICES][dev_id].logger.retrieve_log() # data["log"] = hass.data[DOMAIN][CONF_DEVICES][dev_id].logger.retrieve_log()
return data return data

View File

@@ -7,41 +7,40 @@ from homeassistant.components.vacuum import (
DOMAIN, DOMAIN,
STATE_CLEANING, STATE_CLEANING,
STATE_DOCKED, STATE_DOCKED,
STATE_IDLE,
STATE_RETURNING,
STATE_PAUSED,
STATE_ERROR, STATE_ERROR,
STATE_IDLE,
STATE_PAUSED,
STATE_RETURNING,
SUPPORT_BATTERY, SUPPORT_BATTERY,
SUPPORT_FAN_SPEED, SUPPORT_FAN_SPEED,
SUPPORT_LOCATE,
SUPPORT_PAUSE, SUPPORT_PAUSE,
SUPPORT_RETURN_HOME, SUPPORT_RETURN_HOME,
SUPPORT_START, SUPPORT_START,
SUPPORT_STATE, SUPPORT_STATE,
SUPPORT_STATUS, SUPPORT_STATUS,
SUPPORT_STOP, SUPPORT_STOP,
SUPPORT_LOCATE,
StateVacuumEntity, StateVacuumEntity,
) )
from .common import LocalTuyaEntity, async_setup_entry from .common import LocalTuyaEntity, async_setup_entry
from .const import ( from .const import (
CONF_POWERGO_DP,
CONF_IDLE_STATUS_VALUE,
CONF_RETURNING_STATUS_VALUE,
CONF_DOCKED_STATUS_VALUE,
CONF_BATTERY_DP, CONF_BATTERY_DP,
CONF_MODE_DP,
CONF_MODES,
CONF_FAN_SPEED_DP,
CONF_FAN_SPEEDS,
CONF_CLEAN_TIME_DP,
CONF_CLEAN_AREA_DP, CONF_CLEAN_AREA_DP,
CONF_CLEAN_RECORD_DP, CONF_CLEAN_RECORD_DP,
CONF_LOCATE_DP, CONF_CLEAN_TIME_DP,
CONF_DOCKED_STATUS_VALUE,
CONF_FAN_SPEED_DP,
CONF_FAN_SPEEDS,
CONF_FAULT_DP, CONF_FAULT_DP,
CONF_IDLE_STATUS_VALUE,
CONF_LOCATE_DP,
CONF_MODE_DP,
CONF_MODES,
CONF_PAUSED_STATE, CONF_PAUSED_STATE,
CONF_POWERGO_DP,
CONF_RETURN_MODE, CONF_RETURN_MODE,
CONF_RETURNING_STATUS_VALUE,
CONF_STOP_STATUS, CONF_STOP_STATUS,
) )