diff --git a/custom_components/localtuya/config_flow.py b/custom_components/localtuya/config_flow.py index fed54d7e6..4b2e96986 100644 --- a/custom_components/localtuya/config_flow.py +++ b/custom_components/localtuya/config_flow.py @@ -26,10 +26,12 @@ PLATFORMS, ) from .discovery import discover +from .suggestions import suggest _LOGGER = logging.getLogger(__name__) PLATFORM_TO_ADD = "platform_to_add" +SUGGEST_DPS = "suggest_dps" NO_ADDITIONAL_PLATFORMS = "no_additional_platforms" DISCOVERED_DEVICE = "discovered_device" @@ -65,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, + } ) @@ -107,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): +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: @@ -116,13 +123,19 @@ 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) + + 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): @@ -139,7 +152,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( { @@ -198,10 +212,15 @@ 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 = [] + 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 = {} @@ -284,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 @@ -312,7 +332,12 @@ 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(), + suggest_dps=self.suggest_dps, + ), errors=errors, description_placeholders={"platform": self.platform}, ) 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..e3f2266b7 --- /dev/null +++ b/custom_components/localtuya/suggestions.py @@ -0,0 +1,37 @@ +"""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, dps_in_use): + """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: + # 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 + break + return output + + +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, dps_in_use or []) + 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.""" 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" } },