From f8f170792bfe3b06cc123b0b623007b37410b313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20St=C3=A5hl?= Date: Thu, 29 Oct 2020 10:25:27 +0100 Subject: [PATCH 1/3] Add DP suggestions to switch platforms --- custom_components/localtuya/config_flow.py | 18 ++++++++---- custom_components/localtuya/light.py | 10 ++++++- custom_components/localtuya/suggestions.py | 33 ++++++++++++++++++++++ custom_components/localtuya/switch.py | 8 ++++++ 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 custom_components/localtuya/suggestions.py diff --git a/custom_components/localtuya/config_flow.py b/custom_components/localtuya/config_flow.py index fed54d7e6..ae55cdf06 100644 --- a/custom_components/localtuya/config_flow.py +++ b/custom_components/localtuya/config_flow.py @@ -26,6 +26,7 @@ PLATFORMS, ) from .discovery import discover +from .suggestions import suggest _LOGGER = logging.getLogger(__name__) @@ -116,13 +117,17 @@ def platform_schema(platform, dps_strings, allow_id=True, yaml=False): if allow_id: schema[vol.Required(CONF_ID)] = vol.In(dps_strings) schema[vol.Required(CONF_FRIENDLY_NAME)] = str - return vol.Schema(schema).extend(flow_schema(platform, dps_strings)) - -def flow_schema(platform, dps_strings): - """Return flow schema for a specific platform.""" integration_module = ".".join(__name__.split(".")[:-1]) - return import_module("." + platform, integration_module).flow_schema(dps_strings) + module = import_module("." + platform, integration_module) + + schema.update(module.flow_schema(dps_strings)) + if yaml: + return vol.Schema(schema) + + return schema_defaults( + vol.Schema(schema), dps_strings, **suggest(platform, dps_strings) + ) def strip_dps_values(user_input, dps_strings): @@ -139,7 +144,8 @@ def strip_dps_values(user_input, dps_strings): def config_schema(): """Build schema used for setting up component.""" entity_schemas = [ - platform_schema(platform, range(1, 256), yaml=True) for platform in PLATFORMS + platform_schema(platform, [dp for dp in range(1, 256)], yaml=True) + for platform in PLATFORMS ] return vol.Schema( { diff --git a/custom_components/localtuya/light.py b/custom_components/localtuya/light.py index 628c74d42..8edddafb1 100644 --- a/custom_components/localtuya/light.py +++ b/custom_components/localtuya/light.py @@ -15,7 +15,7 @@ SUPPORT_COLOR_TEMP, LightEntity, ) -from homeassistant.const import CONF_BRIGHTNESS, CONF_COLOR_TEMP +from homeassistant.const import CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_ID from .common import LocalTuyaEntity, async_setup_entry from .const import ( @@ -29,6 +29,14 @@ _LOGGER = logging.getLogger(__name__) +DP_SUGGESTIONS = { + CONF_ID: [1, 20], + CONF_COLOR_MODE: [2, 21], + CONF_BRIGHTNESS: [3, 22], + CONF_COLOR_TEMP: [4, 23], + CONF_COLOR: [5, 24], +} + MIRED_TO_KELVIN_CONST = 1000000 DEFAULT_MIN_KELVIN = 2700 # MIRED 370 DEFAULT_MAX_KELVIN = 6500 # MIRED 153 diff --git a/custom_components/localtuya/suggestions.py b/custom_components/localtuya/suggestions.py new file mode 100644 index 000000000..fd3cb1cf3 --- /dev/null +++ b/custom_components/localtuya/suggestions.py @@ -0,0 +1,33 @@ +"""Module used to suggest datapoints for a platform.""" +from importlib import import_module + +from homeassistant.const import CONF_ID + + +def _suggest_defaults(suggestions, dps_strings): + """Return datapoint suggestions for options.""" + + def _match(suggestion): + for dps_str in dps_strings: + if dps_str.startswith(f"{suggestion} "): + return dps_str + return None + + output = {} + for conf, conf_suggestion in suggestions.items(): + for suggestion in conf_suggestion: + match = _match(suggestion) + if match: + output[conf] = match + break + return output + + +def suggest(platform, dps_strings): + """Suggest datapoints for a platform.""" + integration_module = ".".join(__name__.split(".")[:-1]) + module = import_module("." + platform, integration_module) + + if hasattr(module, "DP_SUGGESTIONS"): + return _suggest_defaults(module.DP_SUGGESTIONS, dps_strings) + return {} diff --git a/custom_components/localtuya/switch.py b/custom_components/localtuya/switch.py index d3e08f553..cfc804ba5 100644 --- a/custom_components/localtuya/switch.py +++ b/custom_components/localtuya/switch.py @@ -4,6 +4,7 @@ import voluptuous as vol from homeassistant.components.switch import DOMAIN, SwitchEntity +from homeassistant.const import CONF_ID from .common import LocalTuyaEntity, async_setup_entry from .const import ( @@ -17,6 +18,13 @@ _LOGGER = logging.getLogger(__name__) +DP_SUGGESTIONS = { + CONF_ID: [1, 2], + CONF_CURRENT: [18], + CONF_CURRENT_CONSUMPTION: [19], + CONF_VOLTAGE: [20], +} + def flow_schema(dps): """Return schema used in config flow.""" From 968e3da3177898c3c33295ae9a5eb3b31b1111d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20St=C3=A5hl?= Date: Sun, 1 Nov 2020 11:05:58 +0100 Subject: [PATCH 2/3] Do not suggest datapoint id used by other entities --- custom_components/localtuya/config_flow.py | 12 +++++++++--- custom_components/localtuya/suggestions.py | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/custom_components/localtuya/config_flow.py b/custom_components/localtuya/config_flow.py index ae55cdf06..6a276fa70 100644 --- a/custom_components/localtuya/config_flow.py +++ b/custom_components/localtuya/config_flow.py @@ -108,7 +108,7 @@ def gen_dps_strings(): return [f"{dp} (value: ?)" for dp in range(1, 256)] -def platform_schema(platform, dps_strings, allow_id=True, yaml=False): +def platform_schema(platform, dps_strings, allow_id=True, yaml=False, dps_in_use=None): """Generate input validation schema for a platform.""" schema = {} if yaml: @@ -126,7 +126,7 @@ def platform_schema(platform, dps_strings, allow_id=True, yaml=False): return vol.Schema(schema) return schema_defaults( - vol.Schema(schema), dps_strings, **suggest(platform, dps_strings) + vol.Schema(schema), dps_strings, **suggest(platform, dps_strings, dps_in_use) ) @@ -208,6 +208,10 @@ def __init__(self): self.selected_device = None self.entities = [] + def async_dps_in_use(self): + """Return datapoints used as ID for entities.""" + return [entity[CONF_ID] for entity in self.entities] + async def async_step_user(self, user_input=None): """Handle the initial step.""" errors = {} @@ -318,7 +322,9 @@ async def async_step_add_entity(self, user_input=None): return self.async_show_form( step_id="add_entity", - data_schema=platform_schema(self.platform, self.dps_strings), + data_schema=platform_schema( + self.platform, self.dps_strings, dps_in_use=self.async_dps_in_use() + ), errors=errors, description_placeholders={"platform": self.platform}, ) diff --git a/custom_components/localtuya/suggestions.py b/custom_components/localtuya/suggestions.py index fd3cb1cf3..f989dad9c 100644 --- a/custom_components/localtuya/suggestions.py +++ b/custom_components/localtuya/suggestions.py @@ -1,10 +1,12 @@ """Module used to suggest datapoints for a platform.""" +from homeassistant.const import CONF_ID + from importlib import import_module from homeassistant.const import CONF_ID -def _suggest_defaults(suggestions, dps_strings): +def _suggest_defaults(suggestions, dps_strings, dps_in_use): """Return datapoint suggestions for options.""" def _match(suggestion): @@ -16,6 +18,10 @@ def _match(suggestion): output = {} for conf, conf_suggestion in suggestions.items(): for suggestion in conf_suggestion: + # Don't suggest an ID that is already in use + if conf == CONF_ID and suggestion in dps_in_use: + continue + match = _match(suggestion) if match: output[conf] = match @@ -23,11 +29,11 @@ def _match(suggestion): return output -def suggest(platform, dps_strings): +def suggest(platform, dps_strings, dps_in_use=None): """Suggest datapoints for a platform.""" integration_module = ".".join(__name__.split(".")[:-1]) module = import_module("." + platform, integration_module) if hasattr(module, "DP_SUGGESTIONS"): - return _suggest_defaults(module.DP_SUGGESTIONS, dps_strings) + return _suggest_defaults(module.DP_SUGGESTIONS, dps_strings, dps_in_use or []) return {} From 368c269d2ca58dcdd81168a94202e30bf22fcf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20St=C3=A5hl?= Date: Fri, 6 Nov 2020 10:08:52 +0100 Subject: [PATCH 3/3] Add checkbox to suggest platform configuration --- custom_components/localtuya/config_flow.py | 25 ++++++++++++++----- custom_components/localtuya/suggestions.py | 2 -- .../localtuya/translations/en.json | 1 + 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/custom_components/localtuya/config_flow.py b/custom_components/localtuya/config_flow.py index 6a276fa70..4b2e96986 100644 --- a/custom_components/localtuya/config_flow.py +++ b/custom_components/localtuya/config_flow.py @@ -31,6 +31,7 @@ _LOGGER = logging.getLogger(__name__) PLATFORM_TO_ADD = "platform_to_add" +SUGGEST_DPS = "suggest_dps" NO_ADDITIONAL_PLATFORMS = "no_additional_platforms" DISCOVERED_DEVICE = "discovered_device" @@ -66,7 +67,10 @@ ) PICK_ENTITY_SCHEMA = vol.Schema( - {vol.Required(PLATFORM_TO_ADD, default=PLATFORMS[0]): vol.In(PLATFORMS)} + { + vol.Required(PLATFORM_TO_ADD, default=PLATFORMS[0]): vol.In(PLATFORMS), + vol.Required(SUGGEST_DPS, default=True): bool, + } ) @@ -108,7 +112,9 @@ def gen_dps_strings(): return [f"{dp} (value: ?)" for dp in range(1, 256)] -def platform_schema(platform, dps_strings, allow_id=True, yaml=False, dps_in_use=None): +def platform_schema( + platform, dps_strings, allow_id=True, yaml=False, dps_in_use=None, suggest_dps=False +): """Generate input validation schema for a platform.""" schema = {} if yaml: @@ -125,9 +131,11 @@ def platform_schema(platform, dps_strings, allow_id=True, yaml=False, dps_in_use if yaml: return vol.Schema(schema) - return schema_defaults( - vol.Schema(schema), dps_strings, **suggest(platform, dps_strings, dps_in_use) - ) + suggestions = {} + if suggest_dps: + suggestions = suggest(platform, dps_strings, dps_in_use) + + return schema_defaults(vol.Schema(schema), dps_strings, **suggestions) def strip_dps_values(user_input, dps_strings): @@ -204,6 +212,7 @@ def __init__(self): self.basic_info = None self.dps_strings = [] self.platform = None + self.suggest_dps = None self.devices = {} self.selected_device = None self.entities = [] @@ -294,6 +303,7 @@ async def async_step_pick_entity_type(self, user_input=None): ) self.platform = user_input[PLATFORM_TO_ADD] + self.suggest_dps = user_input[SUGGEST_DPS] return await self.async_step_add_entity() # Add a checkbox that allows bailing out from config flow iff at least one @@ -323,7 +333,10 @@ async def async_step_add_entity(self, user_input=None): return self.async_show_form( step_id="add_entity", data_schema=platform_schema( - self.platform, self.dps_strings, dps_in_use=self.async_dps_in_use() + self.platform, + self.dps_strings, + dps_in_use=self.async_dps_in_use(), + suggest_dps=self.suggest_dps, ), errors=errors, description_placeholders={"platform": self.platform}, diff --git a/custom_components/localtuya/suggestions.py b/custom_components/localtuya/suggestions.py index f989dad9c..e3f2266b7 100644 --- a/custom_components/localtuya/suggestions.py +++ b/custom_components/localtuya/suggestions.py @@ -1,6 +1,4 @@ """Module used to suggest datapoints for a platform.""" -from homeassistant.const import CONF_ID - from importlib import import_module from homeassistant.const import CONF_ID diff --git a/custom_components/localtuya/translations/en.json b/custom_components/localtuya/translations/en.json index f17184053..dc6fa3588 100644 --- a/custom_components/localtuya/translations/en.json +++ b/custom_components/localtuya/translations/en.json @@ -35,6 +35,7 @@ "description": "Please pick the type of entity you want to add.", "data": { "platform_to_add": "Platform", + "suggest_dps": "Suggest platform configuration", "no_additional_platforms": "Do not add any more entities" } },