From cff5d5a18b228b30be2bb51cca0be9fd54246f81 Mon Sep 17 00:00:00 2001 From: Antony Male Date: Sun, 26 Jan 2025 19:53:19 +0000 Subject: [PATCH] Improve version selection in the options * Pull out the versions to their own section * Make it clearer that ranges have an inclusive start and exclusive end --- .../foxess_modbus/flow/options_handler.py | 95 +++++++++++++------ .../foxess_modbus/translations/en.json | 12 ++- 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/custom_components/foxess_modbus/flow/options_handler.py b/custom_components/foxess_modbus/flow/options_handler.py index 0ad71f5d..97ee2b14 100644 --- a/custom_components/foxess_modbus/flow/options_handler.py +++ b/custom_components/foxess_modbus/flow/options_handler.py @@ -15,6 +15,7 @@ from ..const import POLL_RATE from ..const import ROUND_SENSOR_VALUES from ..inverter_adapters import ADAPTERS +from ..inverter_profiles import Version from ..inverter_profiles import inverter_connection_type_profile_from_config from .adapter_flow_segment import AdapterFlowSegment from .flow_handler_mixin import FlowHandlerMixin @@ -68,7 +69,14 @@ async def body(user_input: dict[str, Any]) -> FlowResult: async def async_step_inverter_options_category(self, _user_input: dict[str, Any] | None = None) -> FlowResult: """Let the user choose what sort of inverter options to configure""" - options = ["select_adapter_type", "inverter_advanced_options"] + _, _, combined_config_options = self._config_for_inverter(self._selected_inverter_id) + versions = inverter_connection_type_profile_from_config(combined_config_options).versions + + options = ["select_adapter_type"] + if len(versions) > 1: + options.append("version_settings") + options.append("inverter_advanced_options") + return self.async_show_menu(step_id="inverter_options_category", menu_options=options) async def async_step_select_adapter_type(self, user_input: dict[str, Any] | None = None) -> FlowResult: @@ -109,15 +117,12 @@ async def async_step_serial_adapter(self, user_input: dict[str, Any] | None = No assert self._adapter_segment is not None return await self._adapter_segment.async_step_serial_adapter(user_input) - async def async_step_inverter_advanced_options(self, user_input: dict[str, Any] | None = None) -> FlowResult: - """Let the user set the selected inverter's advanced settings""" - + async def async_step_version_settings(self, user_input: dict[str, Any] | None = None) -> FlowResult: + """Let the user configure their inverter version""" assert self._selected_inverter_id is not None _, options, combined_config_options = self._config_for_inverter(self._selected_inverter_id) - current_adapter = ADAPTERS[combined_config_options[ADAPTER_ID]] - async def body(user_input: dict[str, Any]) -> FlowResult: version = user_input.get("version") if version is None or version == "latest": @@ -125,6 +130,62 @@ async def body(user_input: dict[str, Any]) -> FlowResult: else: options[INVERTER_VERSION] = version + return self._save_selected_inverter_options(options) + + schema_parts: dict[Any, Any] = {} + + versions = sorted(inverter_connection_type_profile_from_config(combined_config_options).versions.keys()) + assert len(versions) > 1 + + version_options = [] + prev_version = None + # The last element will be None, which means "latest" + for version in versions[:-1]: + # For the sake of clarity, we'll shown an exclusive range as the version one minor version below + # (We don't know whether that version ever actually existed, but that doesn't matter here) + if prev_version is None: + label = f"Earlier than {version}" + else: + inclusive_end = Version(version.major, version.minor - 1) + label = f"{inclusive_end}" if inclusive_end == prev_version else f"{prev_version} - {inclusive_end}" + + version_options.append({"label": label, "value": str(version)}) + prev_version = version + version_options.append({"label": f"{versions[-2]} and higher", "value": "latest"}) # hass can't cope with None + + schema_parts[vol.Required("version", default=options.get(INVERTER_VERSION, "latest"))] = selector( + { + "select": { + "options": list(reversed(version_options)), + "mode": "dropdown", + } + } + ) + + schema = vol.Schema(schema_parts) + + description_placeholders = { + # TODO: Will need changing if we let them set the friendly name / host / port + "inverter": self._create_label_for_inverter(combined_config_options), + } + return await self.with_default_form( + body, + user_input, + "version_settings", + schema, + description_placeholders=description_placeholders, + ) + + async def async_step_inverter_advanced_options(self, user_input: dict[str, Any] | None = None) -> FlowResult: + """Let the user set the selected inverter's advanced settings""" + + assert self._selected_inverter_id is not None + + _, options, combined_config_options = self._config_for_inverter(self._selected_inverter_id) + + current_adapter = ADAPTERS[combined_config_options[ADAPTER_ID]] + + async def body(user_input: dict[str, Any]) -> FlowResult: poll_rate = user_input.get("poll_rate") if poll_rate is not None: options[POLL_RATE] = poll_rate @@ -146,28 +207,6 @@ async def body(user_input: dict[str, Any]) -> FlowResult: schema_parts: dict[Any, Any] = {} - versions = sorted(inverter_connection_type_profile_from_config(combined_config_options).versions.keys()) - if len(versions) > 1: - version_options = [] - prev_version = None - # The last element will be None, which means "latest" - for version in versions[:-1]: - label = f"Up to {version}" if prev_version is None else f"{prev_version} - {version}" - version_options.append({"label": label, "value": str(version)}) - prev_version = version - version_options.append( - {"label": f"{versions[-2]} and higher", "value": "latest"} - ) # hass can't cope with None - - schema_parts[vol.Required("version", default=options.get(INVERTER_VERSION, "latest"))] = selector( - { - "select": { - "options": list(reversed(version_options)), - "mode": "dropdown", - } - } - ) - schema_parts[vol.Required("round_sensor_values", default=options.get(ROUND_SENSOR_VALUES, False))] = selector( {"boolean": {}} ) diff --git a/custom_components/foxess_modbus/translations/en.json b/custom_components/foxess_modbus/translations/en.json index 9593eca9..1f374692 100644 --- a/custom_components/foxess_modbus/translations/en.json +++ b/custom_components/foxess_modbus/translations/en.json @@ -94,6 +94,7 @@ "inverter_options_category": { "menu_options": { "select_adapter_type": "Network settings", + "version_settings": "Version settings", "inverter_advanced_options": "Advanced settings" } }, @@ -134,16 +135,23 @@ "modbus_slave": "This can be set from Settings -> Communication in the inverter menu" } }, + "version_settings": { + "description": "Version settings for \"{inverter}\"", + "data": { + "version": "Inverter's Manager Version" + }, + "data_description": { + "version": "If you're running old inverter firmware, you may be able to select it here" + } + }, "inverter_advanced_options": { "description": "Options for \"{inverter}\".", "data": { - "version": "Inverter Manager Version", "round_sensor_values": "Round sensor values", "poll_rate": "Poll rate (seconds)", "max_read": "Max read" }, "data_description": { - "version": "If you're running old inverter firmware, you may be able to select it here", "round_sensor_values": "Reduces Home Assistant database size by rounding and filtering sensor values", "poll_rate": "The default for your adapter type is {default_poll_rate} seconds. Leave empty to use the default", "max_read": "The default for your adapter type is {default_max_read}. Leave empty to use the default. Warning: Look at the debug log for problems if you increase this!"