Implementing RESET Tuya function to enable devices which are stuck in a zombie mode to start responding to commands. Added configurable DPS for Reset command as found devices wouldn't 'wake up' unless they had exactly the right entries

This commit is contained in:
sibowler
2022-07-20 06:14:12 +10:00
parent 489a6f09fe
commit ad1f757818
7 changed files with 140 additions and 36 deletions

View File

@@ -38,6 +38,7 @@ from .const import (
CONF_NO_CLOUD,
CONF_PRODUCT_NAME,
CONF_PROTOCOL_VERSION,
CONF_RESET_DPIDS,
CONF_SETUP_CLOUD,
CONF_USER_ID,
DATA_CLOUD,
@@ -90,6 +91,7 @@ CONFIGURE_DEVICE_SCHEMA = vol.Schema(
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): str,
vol.Optional(CONF_RESET_DPIDS): str,
}
)
@@ -102,6 +104,7 @@ DEVICE_SCHEMA = vol.Schema(
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): cv.string,
vol.Optional(CONF_RESET_DPIDS): str,
}
)
@@ -144,6 +147,7 @@ def options_schema(entities):
vol.Required(CONF_PROTOCOL_VERSION, default="3.3"): vol.In(["3.1", "3.3"]),
vol.Optional(CONF_SCAN_INTERVAL): int,
vol.Optional(CONF_MANUAL_DPS): str,
vol.Optional(CONF_RESET_DPIDS): str,
vol.Required(
CONF_ENTITIES, description={"suggested_value": entity_names}
): cv.multi_select(entity_names),
@@ -235,6 +239,8 @@ async def validate_input(hass: core.HomeAssistant, data):
detected_dps = {}
interface = None
reset_ids = None
try:
interface = await pytuya.connect(
data[CONF_HOST],
@@ -243,20 +249,39 @@ async def validate_input(hass: core.HomeAssistant, data):
float(data[CONF_PROTOCOL_VERSION]),
)
detected_dps = await interface.detect_available_dps()
try:
detected_dps = await interface.detect_available_dps()
except Exception: # pylint: disable=broad-except
try:
_LOGGER.debug("Initial state update failed, trying reset command")
if CONF_RESET_DPIDS in data:
reset_ids_str = data[CONF_RESET_DPIDS].split(",")
reset_ids = []
for reset_id in reset_ids_str:
reset_ids.append(int(reset_id.strip()))
_LOGGER.debug(
"Reset DPIDs configured: %s (%s)",
data[CONF_RESET_DPIDS],
reset_ids,
)
await interface.reset(reset_ids)
detected_dps = await interface.detect_available_dps()
except Exception: # pylint: disable=broad-except
_LOGGER.debug("No DPS able to be detected")
detected_dps = {}
# if manual DPs are set, merge these.
_LOGGER.debug("Detected DPS: %s", detected_dps)
if CONF_MANUAL_DPS in data:
manual_dps_list = data[CONF_MANUAL_DPS].split(",")
manual_dps_list = [dps.strip() for dps in data[CONF_MANUAL_DPS].split(",")]
_LOGGER.debug(
"Manual DPS Setting: %s (%s)", data[CONF_MANUAL_DPS], manual_dps_list
)
# merge the lists
for new_dps in manual_dps_list:
# trim off any whitespace
new_dps = new_dps.strip()
for new_dps in manual_dps_list + (reset_ids or []):
# If the DPS not in the detected dps list, then add with a
# default value indicating that it has been manually added
if new_dps not in detected_dps:
detected_dps[new_dps] = -1