Second part of one_device_only big merge
This commit is contained in:
@@ -9,8 +9,9 @@ from homeassistant.const import (
|
||||
CONF_ENTITIES,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DOMAIN, TUYA_DEVICE
|
||||
from .config_flow import config_schema
|
||||
from .common import TuyaDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -19,23 +20,17 @@ UNSUB_LISTENER = "unsub_listener"
|
||||
CONFIG_SCHEMA = config_schema()
|
||||
|
||||
|
||||
def import_from_yaml(hass, config, platform):
|
||||
"""Import configuration from YAML."""
|
||||
config[CONF_PLATFORM] = platform
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
|
||||
)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: dict):
|
||||
"""Set up the LocalTuya integration component."""
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
|
||||
print("setup:", config.get(DOMAIN))
|
||||
for host_config in config.get(DOMAIN, []):
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_IMPORT}, data=host_config
|
||||
)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -45,12 +40,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = {
|
||||
UNSUB_LISTENER: unsub_listener,
|
||||
TUYA_DEVICE: TuyaDevice(entry.data),
|
||||
}
|
||||
|
||||
for platform in set(entity[CONF_PLATFORM] for entity in entry.data[CONF_ENTITIES]):
|
||||
for entity in entry.data[CONF_ENTITIES]:
|
||||
platform = entity[CONF_PLATFORM]
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(entry, platform)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@@ -16,8 +16,6 @@ sensor:
|
||||
device_class: current
|
||||
"""
|
||||
import logging
|
||||
from time import time, sleep
|
||||
from threading import Lock
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -26,11 +24,7 @@ from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASSES_SCHEMA,
|
||||
BinarySensorEntity,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_ID,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_FRIENDLY_NAME,
|
||||
)
|
||||
from homeassistant.const import CONF_ID, CONF_DEVICE_CLASS
|
||||
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
@@ -51,7 +45,9 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya sensor based on a config entry."""
|
||||
device, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
@@ -59,7 +55,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device_config in entities_to_setup:
|
||||
sensors.append(
|
||||
LocaltuyaBinarySensor(
|
||||
TuyaCache(device, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
@@ -68,74 +64,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
async_add_entities(sensors, True)
|
||||
|
||||
|
||||
class TuyaCache:
|
||||
"""Cache wrapper for pytuya.TuyaDevice."""
|
||||
|
||||
def __init__(self, device, friendly_name):
|
||||
"""Initialize the cache."""
|
||||
self._cached_status = ""
|
||||
self._cached_status_time = 0
|
||||
self._device = device
|
||||
self._friendly_name = friendly_name
|
||||
self._lock = Lock()
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return unique device identifier."""
|
||||
return self._device.id
|
||||
|
||||
def __get_status(self):
|
||||
for i in range(5):
|
||||
try:
|
||||
status = self._device.status()
|
||||
return status
|
||||
except Exception:
|
||||
print(
|
||||
"Failed to update status of device [{}]".format(
|
||||
self._device.address
|
||||
)
|
||||
)
|
||||
sleep(1.0)
|
||||
if i + 1 == 3:
|
||||
_LOGGER.error(
|
||||
"Failed to update status of device %s", self._device.address
|
||||
)
|
||||
# return None
|
||||
raise ConnectionError("Failed to update status .")
|
||||
|
||||
def set_dps(self, state, dps_index):
|
||||
"""Change the Tuya sensor status and clear the cache."""
|
||||
self._cached_status = ""
|
||||
self._cached_status_time = 0
|
||||
for i in range(5):
|
||||
try:
|
||||
return self._device.set_dps(state, dps_index)
|
||||
except Exception:
|
||||
print(
|
||||
"Failed to set status of device [{}]".format(self._device.address)
|
||||
)
|
||||
if i + 1 == 3:
|
||||
_LOGGER.error(
|
||||
"Failed to set status of device %s", self._device.address
|
||||
)
|
||||
return
|
||||
|
||||
# raise ConnectionError("Failed to set status.")
|
||||
|
||||
def status(self):
|
||||
"""Get state of Tuya sensor and cache the results."""
|
||||
self._lock.acquire()
|
||||
try:
|
||||
now = time()
|
||||
if not self._cached_status or now - self._cached_status_time > 15:
|
||||
sleep(0.5)
|
||||
self._cached_status = self.__get_status()
|
||||
self._cached_status_time = time()
|
||||
return self._cached_status
|
||||
finally:
|
||||
self._lock.release()
|
||||
|
||||
|
||||
class LocaltuyaBinarySensor(LocalTuyaEntity, BinarySensorEntity):
|
||||
"""Representation of a Tuya binary sensor."""
|
||||
|
||||
|
@@ -15,12 +15,12 @@ from homeassistant.const import (
|
||||
)
|
||||
|
||||
from . import pytuya
|
||||
from .const import CONF_LOCAL_KEY, CONF_PROTOCOL_VERSION, DOMAIN
|
||||
from .const import CONF_LOCAL_KEY, CONF_PROTOCOL_VERSION, DOMAIN, TUYA_DEVICE
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def prepare_setup_entities(config_entry, platform):
|
||||
def prepare_setup_entities(hass, config_entry, platform):
|
||||
"""Prepare ro setup entities for a platform."""
|
||||
entities_to_setup = [
|
||||
entity
|
||||
@@ -30,16 +30,7 @@ def prepare_setup_entities(config_entry, platform):
|
||||
if not entities_to_setup:
|
||||
return None, None
|
||||
|
||||
tuyainterface = pytuya.TuyaInterface(
|
||||
config_entry.data[CONF_DEVICE_ID],
|
||||
config_entry.data[CONF_HOST],
|
||||
config_entry.data[CONF_LOCAL_KEY],
|
||||
float(config_entry.data[CONF_PROTOCOL_VERSION]),
|
||||
)
|
||||
|
||||
for entity_config in entities_to_setup:
|
||||
# this has to be done in case the device type is type_0d
|
||||
tuyainterface.add_dps_to_request(entity_config[CONF_ID])
|
||||
tuyainterface = hass.data[DOMAIN][config_entry.entry_id][TUYA_DEVICE]
|
||||
|
||||
return tuyainterface, entities_to_setup
|
||||
|
||||
@@ -55,12 +46,20 @@ def get_entity_config(config_entry, dps_id):
|
||||
class TuyaDevice:
|
||||
"""Cache wrapper for pytuya.TuyaInterface."""
|
||||
|
||||
def __init__(self, interface, friendly_name):
|
||||
def __init__(self, config_entry):
|
||||
"""Initialize the cache."""
|
||||
self._cached_status = ""
|
||||
self._cached_status_time = 0
|
||||
self._interface = interface
|
||||
self._friendly_name = friendly_name
|
||||
self._interface = pytuya.TuyaInterface(
|
||||
config_entry[CONF_DEVICE_ID],
|
||||
config_entry[CONF_HOST],
|
||||
config_entry[CONF_LOCAL_KEY],
|
||||
config_entry[CONF_PROTOCOL_VERSION],
|
||||
)
|
||||
for entity in config_entry[CONF_ENTITIES]:
|
||||
# this has to be done in case the device type is type_0d
|
||||
self._interface.add_dps_to_request(entity[CONF_ID])
|
||||
self._friendly_name = config_entry[CONF_FRIENDLY_NAME]
|
||||
self._lock = Lock()
|
||||
|
||||
@property
|
||||
@@ -90,7 +89,7 @@ class TuyaDevice:
|
||||
|
||||
def set_dps(self, state, dps_index):
|
||||
# _LOGGER.info("running def set_dps from cover")
|
||||
"""Change the Tuya device status and clear the cache."""
|
||||
"""Change the Tuya switch status and clear the cache."""
|
||||
self._cached_status = ""
|
||||
self._cached_status_time = 0
|
||||
for i in range(5):
|
||||
@@ -111,7 +110,7 @@ class TuyaDevice:
|
||||
# raise ConnectionError("Failed to set status.")
|
||||
|
||||
def status(self):
|
||||
"""Get state of Tuya device and cache the results."""
|
||||
"""Get state of Tuya switch and cache the results."""
|
||||
_LOGGER.debug("running def status(self) from TuyaDevice")
|
||||
self._lock.acquire()
|
||||
try:
|
||||
|
@@ -13,7 +13,6 @@ from homeassistant.const import (
|
||||
CONF_DEVICE_ID,
|
||||
CONF_FRIENDLY_NAME,
|
||||
CONF_PLATFORM,
|
||||
CONF_SWITCHES,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
@@ -97,7 +96,6 @@ def schema_defaults(schema, dps_list=None, **defaults):
|
||||
|
||||
if field.schema in defaults:
|
||||
field.default = vol.default_factory(defaults[field])
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
@@ -310,37 +308,21 @@ class LocaltuyaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle import from YAML."""
|
||||
|
||||
def _convert_entity(conf):
|
||||
converted = {
|
||||
CONF_ID: conf[CONF_ID],
|
||||
CONF_FRIENDLY_NAME: conf[CONF_FRIENDLY_NAME],
|
||||
CONF_PLATFORM: self.platform,
|
||||
}
|
||||
for field in flow_schema(self.platform, self.dps_strings).keys():
|
||||
converted[str(field)] = conf[field]
|
||||
return converted
|
||||
for field in flow_schema(conf[CONF_PLATFORM], self.dps_strings).keys():
|
||||
if str(field) in conf:
|
||||
conf[str(field)] = str(conf[field])
|
||||
|
||||
await self.async_set_unique_id(user_input[CONF_DEVICE_ID])
|
||||
self.platform = user_input[CONF_PLATFORM]
|
||||
|
||||
if len(user_input.get(CONF_SWITCHES, [])) > 0:
|
||||
for switch_conf in user_input[CONF_SWITCHES].values():
|
||||
self.entities.append(_convert_entity(switch_conf))
|
||||
else:
|
||||
self.entities.append(_convert_entity(user_input))
|
||||
for entity_conf in user_input[CONF_ENTITIES]:
|
||||
entity_conf[CONF_ID] = str(entity_conf[CONF_ID])
|
||||
_convert_entity(entity_conf)
|
||||
|
||||
# print('ENTITIES: [{}] '.format(self.entities))
|
||||
config = {
|
||||
CONF_FRIENDLY_NAME: f"{user_input[CONF_FRIENDLY_NAME]}",
|
||||
CONF_HOST: user_input[CONF_HOST],
|
||||
CONF_DEVICE_ID: user_input[CONF_DEVICE_ID],
|
||||
CONF_LOCAL_KEY: user_input[CONF_LOCAL_KEY],
|
||||
CONF_PROTOCOL_VERSION: user_input[CONF_PROTOCOL_VERSION],
|
||||
CONF_YAML_IMPORT: True,
|
||||
CONF_ENTITIES: self.entities,
|
||||
}
|
||||
self._abort_if_unique_id_configured(updates=config)
|
||||
user_input[CONF_YAML_IMPORT] = True
|
||||
|
||||
self._abort_if_unique_id_configured(updates=user_input)
|
||||
return self.async_create_entry(
|
||||
title=f"{config[CONF_FRIENDLY_NAME]} (YAML)", data=config
|
||||
title=f"{user_input[CONF_FRIENDLY_NAME]} (YAML)", data=user_input
|
||||
)
|
||||
|
||||
|
||||
|
@@ -26,3 +26,5 @@ DOMAIN = "localtuya"
|
||||
|
||||
# Platforms in this list must support config flows
|
||||
PLATFORMS = ["binary_sensor", "cover", "fan", "light", "sensor", "switch"]
|
||||
|
||||
TUYA_DEVICE = "tuya_device"
|
||||
|
@@ -31,17 +31,14 @@ from homeassistant.components.cover import (
|
||||
SUPPORT_STOP,
|
||||
SUPPORT_SET_POSITION,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_ID,
|
||||
CONF_FRIENDLY_NAME,
|
||||
)
|
||||
from homeassistant.const import CONF_ID
|
||||
|
||||
from .const import (
|
||||
CONF_OPEN_CMD,
|
||||
CONF_CLOSE_CMD,
|
||||
CONF_STOP_CMD,
|
||||
)
|
||||
from .common import LocalTuyaEntity, TuyaDevice, prepare_setup_entities
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -61,7 +58,9 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya cover based on a config entry."""
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
@@ -69,7 +68,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device_config in entities_to_setup:
|
||||
covers.append(
|
||||
LocaltuyaCover(
|
||||
TuyaDevice(tuyainterface, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
@@ -185,7 +184,7 @@ class LocaltuyaCover(LocalTuyaEntity, CoverEntity):
|
||||
|
||||
def stop_cover(self, **kwargs):
|
||||
"""Stop the cover."""
|
||||
_LOGGER.debug("Laudebugching command %s to cover ", self._config[CONF_STOP_CMD])
|
||||
_LOGGER.debug("Launching command %s to cover ", self._config[CONF_STOP_CMD])
|
||||
self._device.set_dps(self._config[CONF_STOP_CMD], self._dps_id)
|
||||
|
||||
def status_updated(self):
|
||||
|
@@ -26,9 +26,9 @@ from homeassistant.components.fan import (
|
||||
SUPPORT_SET_SPEED,
|
||||
SUPPORT_OSCILLATE,
|
||||
)
|
||||
from homeassistant.const import CONF_ID, CONF_FRIENDLY_NAME
|
||||
from homeassistant.const import CONF_ID
|
||||
|
||||
from .common import LocalTuyaEntity, TuyaDevice, prepare_setup_entities
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,7 +40,9 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya fan based on a config entry."""
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
@@ -49,7 +51,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device_config in entities_to_setup:
|
||||
fans.append(
|
||||
LocaltuyaFan(
|
||||
TuyaDevice(tuyainterface, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
|
@@ -13,10 +13,7 @@ light:
|
||||
"""
|
||||
import logging
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_ID,
|
||||
CONF_FRIENDLY_NAME,
|
||||
)
|
||||
from homeassistant.const import CONF_ID
|
||||
from homeassistant.components.light import (
|
||||
LightEntity,
|
||||
DOMAIN,
|
||||
@@ -27,7 +24,7 @@ from homeassistant.components.light import (
|
||||
SUPPORT_COLOR,
|
||||
)
|
||||
|
||||
from .common import LocalTuyaEntity, TuyaDevice, prepare_setup_entities
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -49,18 +46,17 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya light based on a config entry."""
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
lights = []
|
||||
for device_config in entities_to_setup:
|
||||
# this has to be done in case the device type is type_0d
|
||||
tuyainterface.add_dps_to_request(device_config[CONF_ID])
|
||||
|
||||
lights.append(
|
||||
LocaltuyaLight(
|
||||
TuyaDevice(tuyainterface, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
|
@@ -22,13 +22,12 @@ from homeassistant.components.sensor import DOMAIN, DEVICE_CLASSES
|
||||
from homeassistant.const import (
|
||||
CONF_ID,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_FRIENDLY_NAME,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
|
||||
from .const import CONF_SCALING
|
||||
from .common import LocalTuyaEntity, TuyaDevice, prepare_setup_entities
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -48,7 +47,9 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya sensor based on a config entry."""
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
@@ -56,7 +57,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
for device_config in entities_to_setup:
|
||||
sensors.append(
|
||||
LocaltuyaSensor(
|
||||
TuyaDevice(tuyainterface, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
|
@@ -32,10 +32,7 @@ from homeassistant.components.switch import (
|
||||
SwitchEntity,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_ID,
|
||||
CONF_FRIENDLY_NAME,
|
||||
)
|
||||
from homeassistant.const import CONF_ID
|
||||
|
||||
from .const import (
|
||||
ATTR_CURRENT,
|
||||
@@ -45,12 +42,10 @@ from .const import (
|
||||
CONF_CURRENT_CONSUMPTION,
|
||||
CONF_VOLTAGE,
|
||||
)
|
||||
from .common import LocalTuyaEntity, TuyaDevice, prepare_setup_entities
|
||||
from .common import LocalTuyaEntity, prepare_setup_entities
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_ID = "1"
|
||||
|
||||
|
||||
def flow_schema(dps):
|
||||
"""Return schema used in config flow."""
|
||||
@@ -63,24 +58,17 @@ def flow_schema(dps):
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up a Tuya switch based on a config entry."""
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(config_entry, DOMAIN)
|
||||
tuyainterface, entities_to_setup = prepare_setup_entities(
|
||||
hass, config_entry, DOMAIN
|
||||
)
|
||||
if not entities_to_setup:
|
||||
return
|
||||
|
||||
switches = []
|
||||
for device_config in entities_to_setup:
|
||||
if device_config.get(CONF_CURRENT, "-1") != "-1":
|
||||
tuyainterface.add_dps_to_request(device_config.get(CONF_CURRENT))
|
||||
if device_config.get(CONF_CURRENT_CONSUMPTION, "-1") != "-1":
|
||||
tuyainterface.add_dps_to_request(
|
||||
device_config.get(CONF_CURRENT_CONSUMPTION)
|
||||
)
|
||||
if device_config.get(CONF_VOLTAGE, "-1") != "-1":
|
||||
tuyainterface.add_dps_to_request(device_config.get(CONF_VOLTAGE))
|
||||
|
||||
switches.append(
|
||||
LocaltuyaSwitch(
|
||||
TuyaDevice(tuyainterface, config_entry.data[CONF_FRIENDLY_NAME]),
|
||||
tuyainterface,
|
||||
config_entry,
|
||||
device_config[CONF_ID],
|
||||
)
|
||||
|
Reference in New Issue
Block a user