From 3f540d2952f61d2f17e9cf4ca8429449ad1e022e Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Thu, 15 Feb 2024 07:52:27 -0800 Subject: [PATCH 01/30] Changes for inverter id list --- .../solaredge_modbus_multi/__init__.py | 55 +++++++++++--- .../solaredge_modbus_multi/config_flow.py | 76 ++++++++++--------- .../solaredge_modbus_multi/const.py | 15 +++- .../solaredge_modbus_multi/helpers.py | 18 ++--- .../solaredge_modbus_multi/repairs.py | 2 +- .../solaredge_modbus_multi/strings.json | 20 ++--- .../translations/de.json | 14 +--- .../translations/en.json | 20 ++--- .../translations/fr.json | 14 +--- .../translations/it.json | 14 +--- .../translations/nb.json | 14 +--- .../translations/nl.json | 14 +--- .../translations/pl.json | 14 +--- 13 files changed, 141 insertions(+), 149 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 85aca4f9..6d3e8683 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -36,17 +36,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up SolarEdge Modbus Muti from a config entry.""" - entry_updates: dict[str, Any] = {} - if CONF_SCAN_INTERVAL in entry.data: - data = {**entry.data} - entry_updates["data"] = data - entry_updates["options"] = { - **entry.options, - CONF_SCAN_INTERVAL: data.pop(CONF_SCAN_INTERVAL), - } - if entry_updates: - hass.config_entries.async_update_entry(entry, **entry_updates) - solaredge_hub = SolarEdgeModbusMultiHub( hass, entry.entry_id, @@ -169,6 +158,50 @@ async def async_remove_config_entry_device( return True +async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: + """Migrate old entry.""" + _LOGGER.debug("Migrating from version {config_entry.version}") + + if config_entry.version > 1: + return False + + if config_entry.version == 1: + data = {**config_entry.data} + + entry_updates: dict[str, Any] = {} + if CONF_SCAN_INTERVAL in config_entry.data: + entry_updates["data"] = data + entry_updates["options"] = { + **config_entry.options, + CONF_SCAN_INTERVAL: data.pop(CONF_SCAN_INTERVAL), + } + if entry_updates: + hass.config_entries.async_update_entry(config_entry, **entry_updates) + + start_device_id = data.pop(ConfName.DEVICE_ID) + number_of_inverters = data.pop(ConfName.NUMBER_INVERTERS) + + inverter_list = [] + for inverter_index in range(number_of_inverters): + inverter_unit_id = inverter_index + start_device_id + inverter_list.append(inverter_unit_id) + + data["data"] = { + **config_entry.data, + ConfName.DEVICE_LIST: inverter_list, + } + + hass.config_entries.async_update_entry( + config_entry, data=data["data"], version=2, minor_version=0 + ) + + _LOGGER.debug( + f"Migrated to version {config_entry.version}.{config_entry.minor_version}" + ) + + return True + + class SolarEdgeCoordinator(DataUpdateCoordinator): def __init__( self, hass: HomeAssistant, hub: SolarEdgeModbusMultiHub, scan_interval: int diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 3bfaef8c..47660a8e 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -8,9 +8,17 @@ from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SCAN_INTERVAL from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import FlowResult +from homeassistant.exceptions import HomeAssistantError -from .const import DEFAULT_NAME, DOMAIN, ConfDefaultFlag, ConfDefaultInt, ConfName -from .helpers import host_valid +from .const import ( + DEFAULT_NAME, + DOMAIN, + ConfDefaultFlag, + ConfDefaultInt, + ConfDefaultStr, + ConfName, +) +from .helpers import device_list_from_string, host_valid @callback @@ -40,40 +48,39 @@ async def async_step_user(self, user_input=None) -> FlowResult: if user_input is not None: user_input[CONF_HOST] = user_input[CONF_HOST].lower() - if not host_valid(user_input[CONF_HOST]): - errors[CONF_HOST] = "invalid_host" - elif user_input[CONF_HOST] in solaredge_modbus_multi_entries(self.hass): - errors[CONF_HOST] = "already_configured" - elif user_input[CONF_PORT] < 1: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[CONF_PORT] > 65535: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[ConfName.DEVICE_ID] > 247: - errors[ConfName.DEVICE_ID] = "max_device_id" - elif user_input[ConfName.DEVICE_ID] < 1: - errors[ConfName.DEVICE_ID] = "min_device_id" - elif user_input[ConfName.NUMBER_INVERTERS] > 32: - errors[ConfName.NUMBER_INVERTERS] = "max_inverters" - elif user_input[ConfName.NUMBER_INVERTERS] < 1: - errors[ConfName.NUMBER_INVERTERS] = "min_inverters" - elif ( - user_input[ConfName.NUMBER_INVERTERS] + user_input[ConfName.DEVICE_ID] - > 247 - ): - errors[ConfName.NUMBER_INVERTERS] = "too_many_inverters" - else: - await self.async_set_unique_id(user_input[CONF_HOST]) - self._abort_if_unique_id_configured() - return self.async_create_entry( - title=user_input[CONF_NAME], data=user_input + try: + inverter_count = len( + device_list_from_string(user_input[ConfName.DEVICE_LIST]) ) + + except HomeAssistantError as e: + errors[ConfName.DEVICE_LIST] = f"{e}" + + else: + if not host_valid(user_input[CONF_HOST]): + errors[CONF_HOST] = "invalid_host" + elif user_input[CONF_HOST] in solaredge_modbus_multi_entries(self.hass): + errors[CONF_HOST] = "already_configured" + elif user_input[CONF_PORT] < 1: + errors[CONF_PORT] = "invalid_tcp_port" + elif user_input[CONF_PORT] > 65535: + errors[CONF_PORT] = "invalid_tcp_port" + elif inverter_count > 32: + errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" + elif inverter_count < 1: + errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" + else: + await self.async_set_unique_id(user_input[CONF_HOST]) + self._abort_if_unique_id_configured() + return self.async_create_entry( + title=user_input[CONF_NAME], data=user_input + ) else: user_input = { CONF_NAME: DEFAULT_NAME, CONF_HOST: "", CONF_PORT: ConfDefaultInt.PORT, - ConfName.NUMBER_INVERTERS: ConfDefaultInt.NUMBER_INVERTERS, - ConfName.DEVICE_ID: ConfDefaultInt.DEVICE_ID, + ConfName.DEVICE_LIST: ConfDefaultStr.DEVICE_LIST, } return self.async_show_form( @@ -86,12 +93,9 @@ async def async_step_user(self, user_input=None) -> FlowResult: int ), vol.Required( - f"{ConfName.NUMBER_INVERTERS}", - default=user_input[ConfName.NUMBER_INVERTERS], - ): vol.Coerce(int), - vol.Required( - f"{ConfName.DEVICE_ID}", default=user_input[ConfName.DEVICE_ID] - ): vol.Coerce(int), + f"{ConfName.DEVICE_LIST}", + default=user_input[ConfName.DEVICE_LIST], + ): cv.string, }, ), errors=errors, diff --git a/custom_components/solaredge_modbus_multi/const.py b/custom_components/solaredge_modbus_multi/const.py index 20d8f03b..61c5d11a 100644 --- a/custom_components/solaredge_modbus_multi/const.py +++ b/custom_components/solaredge_modbus_multi/const.py @@ -74,8 +74,6 @@ class ConfDefaultInt(IntEnum): SCAN_INTERVAL = 300 PORT = 1502 - NUMBER_INVERTERS = 1 - DEVICE_ID = 1 SLEEP_AFTER_WRITE = 0 BATTERY_RATING_ADJUST = 0 BATTERY_ENERGY_RESET_CYCLES = 0 @@ -94,9 +92,14 @@ class ConfDefaultFlag(IntEnum): ALLOW_BATTERY_ENERGY_RESET = 0 +class ConfDefaultStr(StrEnum): + """Defaults for options that are strings.""" + + DEVICE_LIST = "1" + + class ConfName(StrEnum): - NUMBER_INVERTERS = "number_of_inverters" - DEVICE_ID = "device_id" + DEVICE_LIST = "device_list" DETECT_METERS = "detect_meters" DETECT_BATTERIES = "detect_batteries" DETECT_EXTRAS = "detect_extras" @@ -109,6 +112,10 @@ class ConfName(StrEnum): BATTERY_RATING_ADJUST = "battery_rating_adjust" BATTERY_ENERGY_RESET_CYCLES = "battery_energy_reset_cycles" + # Old config entry names for migration + NUMBER_INVERTERS = "number_of_inverters" + DEVICE_ID = "device_id" + class SunSpecAccum(IntEnum): NA16 = 0x0000 diff --git a/custom_components/solaredge_modbus_multi/helpers.py b/custom_components/solaredge_modbus_multi/helpers.py index 18d760ef..a9dd177a 100644 --- a/custom_components/solaredge_modbus_multi/helpers.py +++ b/custom_components/solaredge_modbus_multi/helpers.py @@ -47,8 +47,8 @@ def host_valid(host): return DOMAIN_REGEX.match(host) -def deviceIdsFromString(value: str) -> list[int]: - """The function `deviceIdsFromString` takes a string input and returns a list of +def device_list_from_string(value: str) -> list[int]: + """The function `device_list_from_string` takes a string input and returns a list of device IDs, where the input can be a single ID or a range of IDs separated by commas Parameters @@ -60,7 +60,7 @@ def deviceIdsFromString(value: str) -> list[int]: Returns ------- - The function `checkDeviceIds` returns a list of device IDs. + The function `device_list_from_string` returns a list of device IDs. Credit: https://github.com/thargy/modbus-scanner/blob/main/scan.py """ @@ -70,7 +70,7 @@ def deviceIdsFromString(value: str) -> list[int]: r = [i.strip() for i in p.split("-")] if len(r) < 2: # We have a single id - ids.append(checkDeviceId(r[0])) + ids.append(check_device_id(r[0])) elif len(r) > 2: # Invalid range, multiple '-'s @@ -80,8 +80,8 @@ def deviceIdsFromString(value: str) -> list[int]: else: # Looks like a range - start = checkDeviceId(r[0]) - end = checkDeviceId(r[1]) + start = check_device_id(r[0]) + end = check_device_id(r[1]) if end < start: raise HomeAssistantError( f"'{start}' must be less than or equal to {end}." @@ -92,8 +92,8 @@ def deviceIdsFromString(value: str) -> list[int]: return sorted(set(ids)) -def checkDeviceId(value: (str | int)) -> int: - """The `checkDeviceId` function takes a value and checks if it is a valid device +def check_device_id(value: (str | int)) -> int: + """The `check_device_id` function takes a value and checks if it is a valid device ID between 1 and 247, raising an error if it is not. Parameters @@ -111,6 +111,6 @@ def checkDeviceId(value: (str | int)) -> int: id = int(value) if (id < 1) or id > 247: - raise HomeAssistantError(f"'{value}' must be a device ID between 1 and 247") + raise HomeAssistantError("invalid_device_id") return id diff --git a/custom_components/solaredge_modbus_multi/repairs.py b/custom_components/solaredge_modbus_multi/repairs.py index 52ea1baa..1a383e3a 100644 --- a/custom_components/solaredge_modbus_multi/repairs.py +++ b/custom_components/solaredge_modbus_multi/repairs.py @@ -48,7 +48,7 @@ async def async_step_confirm( elif user_input[CONF_PORT] > 65535: errors[CONF_PORT] = "invalid_tcp_port" elif user_input[ConfName.DEVICE_ID] > 247: - errors[ConfName.DEVICE_ID] = "max_device_id" + errors[ConfName.DEVICE_ID] = "invalid_device_id" elif user_input[ConfName.DEVICE_ID] < 1: errors[ConfName.DEVICE_ID] = "min_device_id" elif user_input[ConfName.NUMBER_INVERTERS] > 32: diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index af880f79..4566d435 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -7,18 +7,14 @@ "name": "Sensor Prefix", "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, "error": { "already_configured": "Device is already configured!", - "max_device_id": "Device ID must be between 1 to 247.", - "min_device_id": "Device ID must be between 1 to 247.", - "max_inverters": "Must be between 1 to 32 inverters.", - "min_inverters": "Must be between 1 to 32 inverters.", - "too_many_inverters": "Number of inverters too high for Device ID.", + "invalid_device_id": "Device ID must be between 1 to 247.", + "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535." }, @@ -74,17 +70,13 @@ "data": { "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, "error": { - "max_device_id": "Device ID must be between 1 to 247.", - "min_device_id": "Device ID must be between 1 to 247.", - "max_inverters": "Must be between 1 to 32 inverters.", - "min_inverters": "Must be between 1 to 32 inverters.", - "too_many_inverters": "Number of inverters too high for Device ID.", + "invalid_device_id": "Device ID must be between 1 to 247.", + "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index ec955e8f..3202fd4f 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "Der Wechselrichter ist bereits konfiguriert.", - "max_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", - "min_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", - "max_inverters": "Muss zwischen 1 und 32 Wechselrichtern liegen.", - "min_inverters": "Muss zwischen 1 und 32 Wechselrichtern liegen.", - "too_many_inverters": "Anzahl Wechselrichter zu hoch für Geräte-ID.", + "invalid_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", + "invalid_inverter_count": "Muss zwischen 1 und 32 Wechselrichtern liegen.", "invalid_host": "Ungültige IP-Adresse.", "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", - "min_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", - "max_inverters": "Muss zwischen 1 und 32 Wechselrichtern liegen.", - "min_inverters": "Muss zwischen 1 und 32 Wechselrichtern liegen.", - "too_many_inverters": "Anzahl Wechselrichter zu hoch für Geräte-ID.", + "invalid_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", + "invalid_inverter_count": "Muss zwischen 1 und 32 Wechselrichtern liegen.", "invalid_host": "Ungültige IP-Adresse.", "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index af880f79..4566d435 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -7,18 +7,14 @@ "name": "Sensor Prefix", "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, "error": { "already_configured": "Device is already configured!", - "max_device_id": "Device ID must be between 1 to 247.", - "min_device_id": "Device ID must be between 1 to 247.", - "max_inverters": "Must be between 1 to 32 inverters.", - "min_inverters": "Must be between 1 to 32 inverters.", - "too_many_inverters": "Number of inverters too high for Device ID.", + "invalid_device_id": "Device ID must be between 1 to 247.", + "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535." }, @@ -74,17 +70,13 @@ "data": { "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, "error": { - "max_device_id": "Device ID must be between 1 to 247.", - "min_device_id": "Device ID must be between 1 to 247.", - "max_inverters": "Must be between 1 to 32 inverters.", - "min_inverters": "Must be between 1 to 32 inverters.", - "too_many_inverters": "Number of inverters too high for Device ID.", + "invalid_device_id": "Device ID must be between 1 to 247.", + "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index 0f3d9d7d..4aac7697 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "L'appareil est déjà configuré!", - "max_device_id": "L'adresse Modbus doit être entre 1 et 247.", - "min_device_id": "L'adresse Modbus doit être entre 1 et 247.", - "max_inverters": "Doit être entre 1 et 32 onduleurs.", - "min_inverters": "Doit être entre 1 et 32 onduleurs.", - "too_many_inverters": "Nombre d'onduleurs trop important pour l'adresse Modbus.", + "invalid_device_id": "L'adresse Modbus doit être entre 1 et 247.", + "invalid_inverter_count": "Doit être entre 1 et 32 onduleurs.", "invalid_host": "Adresse IP invalide.", "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "L'adresse Modbus doit être entre 1 et 247.", - "min_device_id": "L'adresse Modbus doit être entre 1 et 247.", - "max_inverters": "Doit être entre 1 et 32 onduleurs.", - "min_inverters": "Doit être entre 1 et 32 onduleurs.", - "too_many_inverters": "Nombre d'onduleurs trop important pour l'adresse Modbus.", + "invalid_device_id": "L'adresse Modbus doit être entre 1 et 247.", + "invalid_inverter_count": "Doit être entre 1 et 32 onduleurs.", "invalid_host": "Adresse IP invalide.", "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 6342e5c5..b248db69 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "Il dispositivo è già configurato!", - "max_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", - "min_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", - "max_inverters": "Deve essere compreso tra 1 e 32 inverter.", - "min_inverters": "Deve essere compreso tra 1 e 32 inverter.", - "too_many_inverters": "Numero di inverter troppo elevato per l'ID dispositivo.", + "invalid_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", + "invalid_inverter_count": "Deve essere compreso tra 1 e 32 inverter.", "invalid_host": "Indirizzo IP non valido.", "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", - "min_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", - "max_inverters": "Deve essere compreso tra 1 e 32 inverter.", - "min_inverters": "Deve essere compreso tra 1 e 32 inverter.", - "too_many_inverters": "Numero di inverter troppo elevato per l'ID dispositivo.", + "invalid_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", + "invalid_inverter_count": "Deve essere compreso tra 1 e 32 inverter.", "invalid_host": "Indirizzo IP non valido.", "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index 689b06b1..c0342148 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "Enheten er allerede konfigurert", - "max_device_id": "Enhets-ID må være mellom 1 og 247.", - "min_device_id": "Enhets-ID må være mellom 1 og 247.", - "max_inverters": "Må være mellom 1 og 32 omformere.", - "min_inverters": "Må være mellom 1 og 32 omformere.", - "too_many_inverters": "Antall invertere for høyt for enhets-ID.", + "invalid_device_id": "Enhets-ID må være mellom 1 og 247.", + "invalid_inverter_count": "Må være mellom 1 og 32 omformere.", "invalid_host": "Ugyldig IP-adresse.", "invalid_tcp_port": "Gyldig portområde er 1 til 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "Enhets-ID må være mellom 1 og 247.", - "min_device_id": "Enhets-ID må være mellom 1 og 247.", - "max_inverters": "Må være mellom 1 og 32 omformere.", - "min_inverters": "Må være mellom 1 og 32 omformere.", - "too_many_inverters": "Antall invertere for høyt for enhets-ID.", + "invalid_device_id": "Enhets-ID må være mellom 1 og 247.", + "invalid_inverter_count": "Må være mellom 1 og 32 omformere.", "invalid_host": "Ugyldig IP-adresse.", "invalid_tcp_port": "Gyldig portområde er 1 til 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 5455664f..9a8d50d0 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "Apparaat is al geconfigureerd", - "max_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", - "min_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", - "max_inverters": "Moet tussen 1 en 32 omvormers zijn.", - "min_inverters": "Moet tussen 1 en 32 omvormers zijn.", - "too_many_inverters": "Aantal omvormers te hoog voor Device ID.", + "invalid_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", + "invalid_inverter_count": "Moet tussen 1 en 32 omvormers zijn.", "invalid_host": "Ongeldig IP-adres.", "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", - "min_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", - "max_inverters": "Moet tussen 1 en 32 omvormers zijn.", - "min_inverters": "Moet tussen 1 en 32 omvormers zijn.", - "too_many_inverters": "Aantal omvormers te hoog voor Device ID.", + "invalid_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", + "invalid_inverter_count": "Moet tussen 1 en 32 omvormers zijn.", "invalid_host": "Ongeldig IP-adres.", "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535." } diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index 7580c62b..f98c2300 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -14,11 +14,8 @@ }, "error": { "already_configured": "Urządzenie jest już skonfigurowane!", - "max_device_id": "Device ID musi być pomiędzy 1 i 247.", - "min_device_id": "Device ID musi być pomiędzy 1 i 247.", - "max_inverters": "Dopuszczalna liczba inwerterów to od 1 do 32.", - "min_inverters": "Dopuszczalna liczba inwerterów to od 1 do 32.", - "too_many_inverters": "Liczba inwerterów za duża dla Device ID.", + "invalid_device_id": "Device ID musi być pomiędzy 1 i 247.", + "invalid_inverter_count": "Dopuszczalna liczba inwerterów to od 1 do 32.", "invalid_host": "Błędny adres IP.", "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535." }, @@ -80,11 +77,8 @@ } }, "error": { - "max_device_id": "Device ID musi być pomiędzy 1 i 247.", - "min_device_id": "Device ID musi być pomiędzy 1 i 247.", - "max_inverters": "Dopuszczalna liczba inwerterów to od 1 do 32.", - "min_inverters": "Dopuszczalna liczba inwerterów to od 1 do 32.", - "too_many_inverters": "Liczba inwerterów za duża dla Device ID.", + "invalid_device_id": "Device ID musi być pomiędzy 1 i 247.", + "invalid_inverter_count": "Dopuszczalna liczba inwerterów to od 1 do 32.", "invalid_host": "Błędny adres IP.", "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535." } From 86b3ca59914fe4a69a33afe3798df024532d9427 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:01:57 -0700 Subject: [PATCH 02/30] Update helpers.py --- custom_components/solaredge_modbus_multi/helpers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/helpers.py b/custom_components/solaredge_modbus_multi/helpers.py index 0a8955e3..a20e900d 100644 --- a/custom_components/solaredge_modbus_multi/helpers.py +++ b/custom_components/solaredge_modbus_multi/helpers.py @@ -73,7 +73,7 @@ def device_list_from_string(value: str) -> list[int]: elif len(r) > 2: # Invalid range, multiple '-'s raise HomeAssistantError( - f"'{p}' in '{value}' looks like a range but has multiple '-'s." + f"Entry '{p}' in '{value}' looks like a range but has multiple '-'s." ) else: @@ -82,7 +82,7 @@ def device_list_from_string(value: str) -> list[int]: end = check_device_id(r[1]) if end < start: raise HomeAssistantError( - f"'{start}' must be less than or equal to {end}." + f"ID '{start}' must be less than or equal to {end}." ) ids.extend(range(start, end + 1)) @@ -109,6 +109,6 @@ def check_device_id(value: (str | int)) -> int: id = int(value) if (id < 1) or id > 247: - raise HomeAssistantError("invalid_device_id") + raise HomeAssistantError("Value outside range 1-247.") return id From f7e715ec8ad6d6903ba2d9d15224f06ed9fd0d33 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:22:53 -0700 Subject: [PATCH 03/30] Update __init__.py --- custom_components/solaredge_modbus_multi/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 46ef2130..46742d2a 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -16,7 +16,7 @@ from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import DOMAIN, ConfDefaultInt, RetrySettings +from .const import DOMAIN, ConfDefaultInt, ConfName, RetrySettings from .hub import DataUpdateFailed, HubInitFailed, SolarEdgeModbusMultiHub _LOGGER = logging.getLogger(__name__) From 24e7225a80c4c53e2caa98af319ef52201830b0c Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:24:59 -0700 Subject: [PATCH 04/30] Update helpers.py --- custom_components/solaredge_modbus_multi/helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/solaredge_modbus_multi/helpers.py b/custom_components/solaredge_modbus_multi/helpers.py index a20e900d..e89fdddc 100644 --- a/custom_components/solaredge_modbus_multi/helpers.py +++ b/custom_components/solaredge_modbus_multi/helpers.py @@ -3,6 +3,8 @@ import ipaddress import struct +from homeassistant.exceptions import HomeAssistantError + from .const import DOMAIN_REGEX @@ -90,7 +92,7 @@ def device_list_from_string(value: str) -> list[int]: return sorted(set(ids)) -def check_device_id(value: (str | int)) -> int: +def check_device_id(value: str | int) -> int: """The `check_device_id` function takes a value and checks if it is a valid device ID between 1 and 247, raising an error if it is not. From 780e92f8fd0c5dc96acecb1ca3a0b6f7062734b1 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:25:15 -0700 Subject: [PATCH 05/30] Log config migration as warning --- custom_components/solaredge_modbus_multi/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 46742d2a..6a00a0ac 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -194,8 +194,8 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> config_entry, data=data["data"], version=2, minor_version=0 ) - _LOGGER.debug( - f"Migrated to version {config_entry.version}.{config_entry.minor_version}" + _LOGGER.warning( + f"Migrated config to version {config_entry.version}.{config_entry.minor_version}" ) return True From 6bd988014c92ad3bc0a61e10f848a574864fc3d6 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:25:27 -0700 Subject: [PATCH 06/30] Config version 2.0 --- custom_components/solaredge_modbus_multi/config_flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 936a293b..783cb8ed 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -36,8 +36,8 @@ def solaredge_modbus_multi_entries(hass: HomeAssistant): class SolaredgeModbusMultiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow for SolarEdge Modbus Multi.""" - VERSION = 1 - MINOR_VERSION = 1 + VERSION = 2 + MINOR_VERSION = 0 @staticmethod @callback From 27ee8345a11fdc3ad2bc49d53f6efa11655f2687 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:32:01 -0700 Subject: [PATCH 07/30] Convert hub to use inverter id list --- custom_components/solaredge_modbus_multi/hub.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/hub.py b/custom_components/solaredge_modbus_multi/hub.py index b9038e8e..5582208e 100644 --- a/custom_components/solaredge_modbus_multi/hub.py +++ b/custom_components/solaredge_modbus_multi/hub.py @@ -118,11 +118,8 @@ def __init__( self._host = entry_data[CONF_HOST] self._port = entry_data[CONF_PORT] self._entry_id = entry_id - self._number_of_inverters = entry_data.get( - ConfName.NUMBER_INVERTERS, ConfDefaultInt.NUMBER_INVERTERS - ) - self._start_device_id = entry_data.get( - ConfName.DEVICE_ID, ConfDefaultInt.DEVICE_ID + self._inverter_list = entry_data.get( + ConfName.DEVICE_LIST, ConfDefaultInt.DEVICE_ID ) self._detect_meters = entry_options.get( ConfName.DETECT_METERS, bool(ConfDefaultFlag.DETECT_METERS) @@ -190,8 +187,7 @@ def __init__( _LOGGER.debug( ( f"{DOMAIN} configuration: " - f"number_of_inverters={self._number_of_inverters}, " - f"start_device_id={self._start_device_id}, " + f"inverter_list={self._inverter_list}, " f"detect_meters={self._detect_meters}, " f"detect_batteries={self._detect_batteries}, " f"detect_extras={self._detect_extras}, " @@ -237,8 +233,7 @@ async def _async_init_solaredge(self) -> None: ), ) - for inverter_index in range(self._number_of_inverters): - inverter_unit_id = inverter_index + self._start_device_id + for inverter_unit_id in self._inverter_list: try: _LOGGER.debug( @@ -704,7 +699,7 @@ def number_of_batteries(self) -> int: @property def number_of_inverters(self) -> int: - return self._number_of_inverters + return len(self._inverter_list) @property def sleep_after_write(self) -> int: From d565febab92a5db83ca7383359549ca3a2f7bf8c Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:42:03 -0700 Subject: [PATCH 08/30] Default device list --- custom_components/solaredge_modbus_multi/hub.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/solaredge_modbus_multi/hub.py b/custom_components/solaredge_modbus_multi/hub.py index 5582208e..90f18748 100644 --- a/custom_components/solaredge_modbus_multi/hub.py +++ b/custom_components/solaredge_modbus_multi/hub.py @@ -25,6 +25,7 @@ METER_REG_BASE, ConfDefaultFlag, ConfDefaultInt, + ConfDefaultStr, ConfName, ModbusDefaults, ModbusFlags, @@ -119,7 +120,7 @@ def __init__( self._port = entry_data[CONF_PORT] self._entry_id = entry_id self._inverter_list = entry_data.get( - ConfName.DEVICE_LIST, ConfDefaultInt.DEVICE_ID + ConfName.DEVICE_LIST, [ConfDefaultStr.DEVICE_LIST] ) self._detect_meters = entry_options.get( ConfName.DETECT_METERS, bool(ConfDefaultFlag.DETECT_METERS) From de7a0a000822b1d61f45ee310f9fa105b0dbd5a8 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:07:52 -0700 Subject: [PATCH 09/30] Strip whitespace from user entry --- custom_components/solaredge_modbus_multi/config_flow.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 783cb8ed..8c0af3b5 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -2,6 +2,7 @@ from __future__ import annotations +import re from typing import Any import homeassistant.helpers.config_validation as cv @@ -53,6 +54,9 @@ async def async_step_user( if user_input is not None: user_input[CONF_HOST] = user_input[CONF_HOST].lower() + user_input[ConfName.DEVICE_LIST] = re.sub( + r"\s+", "", user_input[ConfName.DEVICE_LIST], flags=re.UNICODE + ) try: inverter_count = len( From 9b47f8343a44e0621867c2df4b1798d065f8f4a5 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:09:00 -0700 Subject: [PATCH 10/30] Raise translation keys for device list errors --- .../solaredge_modbus_multi/helpers.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/helpers.py b/custom_components/solaredge_modbus_multi/helpers.py index e89fdddc..544a8d61 100644 --- a/custom_components/solaredge_modbus_multi/helpers.py +++ b/custom_components/solaredge_modbus_multi/helpers.py @@ -74,18 +74,14 @@ def device_list_from_string(value: str) -> list[int]: elif len(r) > 2: # Invalid range, multiple '-'s - raise HomeAssistantError( - f"Entry '{p}' in '{value}' looks like a range but has multiple '-'s." - ) + raise HomeAssistantError("invalid_range_format") else: # Looks like a range start = check_device_id(r[0]) end = check_device_id(r[1]) if end < start: - raise HomeAssistantError( - f"ID '{start}' must be less than or equal to {end}." - ) + raise HomeAssistantError("invalid_range_lte") ids.extend(range(start, end + 1)) @@ -108,9 +104,17 @@ def check_device_id(value: str | int) -> int: Credit: https://github.com/thargy/modbus-scanner/blob/main/scan.py """ - id = int(value) - if (id < 1) or id > 247: - raise HomeAssistantError("Value outside range 1-247.") + if len(value) == 0: + raise HomeAssistantError("empty_device_id") + + try: + id = int(value) + + if (id < 1) or id > 247: + raise HomeAssistantError("invalid_device_id") + + except ValueError: + raise HomeAssistantError("invalid_device_id") return id From 3c755a40cdc5e6fa4872fbb499d6424b7039ccbd Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:11:45 -0700 Subject: [PATCH 11/30] Remove old translation keys --- custom_components/solaredge_modbus_multi/translations/de.json | 3 +-- custom_components/solaredge_modbus_multi/translations/fr.json | 3 +-- custom_components/solaredge_modbus_multi/translations/it.json | 3 +-- custom_components/solaredge_modbus_multi/translations/nb.json | 3 +-- custom_components/solaredge_modbus_multi/translations/nl.json | 3 +-- custom_components/solaredge_modbus_multi/translations/pl.json | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index 51ea3d96..3dafec71 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -7,8 +7,7 @@ "name": "Sensorpräfix", "host": "Wechselrichter-IP-Adresse", "port": "Modbus/TCP-Port", - "device_id": "Wechselrichter-Modbus-Adresse (Geräte-ID)", - "number_of_inverters": "Anzahl Wechselrichter" + "device_id": "Wechselrichter-Modbus-Adresse (Geräte-ID)" } }, "reconfigure": { diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index b5761a58..cf5f0fd8 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -7,8 +7,7 @@ "name": "Prefix du capteur", "host": "Adresse IP de l'onduleur", "port": "Port Modbus/TCP", - "device_id": "L'adresse Modbus de l'onduleur (Device ID)", - "number_of_inverters": "Nombre d'onduleurs" + "device_id": "L'adresse Modbus de l'onduleur (Device ID)" } }, "reconfigure": { diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index b44e07e4..18be10ca 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -7,8 +7,7 @@ "name": "Prefisso sensore", "host": "Indirizzo IP dell'inverter", "port": "Porta Modbus/TCP", - "device_id": "Indirizzo Modbus dell'inverter (ID dispositivo)", - "number_of_inverters": "Numero di inverter" + "device_id": "Indirizzo Modbus dell'inverter (ID dispositivo)" } }, "reconfigure": { diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index da4e48dc..6c6fb90b 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -7,8 +7,7 @@ "name": "Sensorvoorvoegsel", "host": "IP-adres van omvormer", "port": "Modbus/TCP-poort", - "device_id": "Inverter Modbus-adresse (enhets-ID)", - "number_of_inverters": "Antall omformere koblet sammen" + "device_id": "Inverter Modbus-adresse (enhets-ID)" } }, "reconfigure": { diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 7df81c4c..7b49323f 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -7,8 +7,7 @@ "name": "Sensor prefix", "host": "omvormer IP-adres", "port": "Modbus/TCP Port", - "device_id": "Omvormer Modbus-adres (apparaat-ID)", - "number_of_inverters": "Aantal aangesloten omvormers" + "device_id": "Omvormer Modbus-adres (apparaat-ID)" } }, "reconfigure": { diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index 74c6c9e3..f59d9283 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -7,8 +7,7 @@ "name": "Prefix sensora", "host": "Adres IP inwertera", "port": "Modbus/TCP Port", - "device_id": "Adres Modbus Inwertera (Device ID)", - "number_of_inverters": "Ilość inwerterów" + "device_id": "Adres Modbus Inwertera (Device ID)" } }, "reconfigure": { From 37dcea3c60ab181066287cef0e164fcca7172be8 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:18:30 -0700 Subject: [PATCH 12/30] Update translations for config step --- custom_components/solaredge_modbus_multi/strings.json | 4 +++- custom_components/solaredge_modbus_multi/translations/de.json | 4 +++- custom_components/solaredge_modbus_multi/translations/en.json | 4 +++- custom_components/solaredge_modbus_multi/translations/fr.json | 4 +++- custom_components/solaredge_modbus_multi/translations/it.json | 4 +++- custom_components/solaredge_modbus_multi/translations/nb.json | 4 +++- custom_components/solaredge_modbus_multi/translations/nl.json | 4 +++- custom_components/solaredge_modbus_multi/translations/pl.json | 4 +++- 8 files changed, 24 insertions(+), 8 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index 4cfb5729..2ea8a787 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -25,7 +25,9 @@ "invalid_device_id": "Device ID must be between 1 to 247.", "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", - "invalid_tcp_port": "Valid port range is 1 to 65535." + "invalid_tcp_port": "Valid port range is 1 to 65535.", + "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID." }, "abort": { "already_configured": "Device is already configured", diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index 3dafec71..d7d22eee 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -25,7 +25,9 @@ "invalid_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", "invalid_inverter_count": "Muss zwischen 1 und 32 Wechselrichtern liegen.", "invalid_host": "Ungültige IP-Adresse.", - "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535." + "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535.", + "invalid_range_format": "Der Eintrag sieht aus wie ein Bereich, es ist jedoch nur ein „-“ pro Bereich zulässig.", + "invalid_range_lte": "Die Start-ID in einem Bereich muss kleiner oder gleich der End-ID sein." }, "abort": { "already_configured": "Gerät ist bereits konfiguriert", diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index 4cfb5729..2ea8a787 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -25,7 +25,9 @@ "invalid_device_id": "Device ID must be between 1 to 247.", "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", - "invalid_tcp_port": "Valid port range is 1 to 65535." + "invalid_tcp_port": "Valid port range is 1 to 65535.", + "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID." }, "abort": { "already_configured": "Device is already configured", diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index cf5f0fd8..3ab0d761 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -25,7 +25,9 @@ "invalid_device_id": "L'adresse Modbus doit être entre 1 et 247.", "invalid_inverter_count": "Doit être entre 1 et 32 onduleurs.", "invalid_host": "Adresse IP invalide.", - "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535." + "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535.", + "invalid_range_format": "L'entrée ressemble à une plage mais un seul « - » par plage est autorisé.", + "invalid_range_lte": "L’ID de début d’une plage doit être inférieur ou égal à l’ID de fin." }, "abort": { "already_configured": "L'appareil est déjà configuré", diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 18be10ca..6047239d 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -25,7 +25,9 @@ "invalid_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", "invalid_inverter_count": "Deve essere compreso tra 1 e 32 inverter.", "invalid_host": "Indirizzo IP non valido.", - "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535." + "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535.", + "invalid_range_format": "L'immissione sembra un intervallo ma è consentito solo un '-' per intervallo.", + "invalid_range_lte": "L'ID iniziale in un intervallo deve essere inferiore o uguale all'ID finale." }, "abort": { "already_configured": "Il dispositivo è già configurato", diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index 6c6fb90b..94131418 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -25,7 +25,9 @@ "invalid_device_id": "Enhets-ID må være mellom 1 og 247.", "invalid_inverter_count": "Må være mellom 1 og 32 omformere.", "invalid_host": "Ugyldig IP-adresse.", - "invalid_tcp_port": "Gyldig portområde er 1 til 65535." + "invalid_tcp_port": "Gyldig portområde er 1 til 65535.", + "invalid_range_format": "Oppføring ser ut som et område, men bare én '-' per område er tillatt.", + "invalid_range_lte": "Start-ID i et område må være mindre enn eller lik slutt-ID." }, "abort": { "already_configured": "Enheten er allerede konfigurert", diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 7b49323f..70573c7f 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -25,7 +25,9 @@ "invalid_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", "invalid_inverter_count": "Moet tussen 1 en 32 omvormers zijn.", "invalid_host": "Ongeldig IP-adres.", - "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535." + "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535.", + "invalid_range_format": "Invoer ziet eruit als een bereik, maar er is slechts één '-' per bereik toegestaan.", + "invalid_range_lte": "De start-ID in een bereik moet kleiner zijn dan of gelijk zijn aan de eind-ID." }, "abort": { "already_configured": "Apparaat is al geconfigureerd", diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index f59d9283..054f6264 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -25,7 +25,9 @@ "invalid_device_id": "Device ID musi być pomiędzy 1 i 247.", "invalid_inverter_count": "Dopuszczalna liczba inwerterów to od 1 do 32.", "invalid_host": "Błędny adres IP.", - "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535." + "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535.", + "invalid_range_format": "Wpis wygląda jak zakres, ale dozwolony jest tylko jeden znak „-” na zakres.", + "invalid_range_lte": "Początkowy identyfikator w zakresie musi być mniejszy lub równy identyfikatorowi końcowemu." }, "abort": { "already_configured": "Urządzenie jest już skonfigurowane", From f7d9e96ae16a6f41567bc62cde394a5c7bef534c Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:56:36 -0700 Subject: [PATCH 13/30] Update config_flow.py --- custom_components/solaredge_modbus_multi/config_flow.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 8c0af3b5..caa3a79e 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -82,6 +82,11 @@ async def async_step_user( else: await self.async_set_unique_id(user_input[CONF_HOST]) self._abort_if_unique_id_configured() + + user_input[ConfName.DEVICE_LIST] = device_list_from_string( + user_input[ConfName.DEVICE_LIST] + ) + return self.async_create_entry( title=user_input[CONF_NAME], data=user_input ) From 4eaafc8a87a7c84afdb85790e93fc66359e1c46c Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:31:51 -0700 Subject: [PATCH 14/30] Clean up config migration --- .../solaredge_modbus_multi/__init__.py | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 6a00a0ac..a675598d 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -5,7 +5,6 @@ import asyncio import logging from datetime import timedelta -from typing import Any import homeassistant.helpers.config_validation as cv import voluptuous as vol @@ -165,37 +164,39 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> return False if config_entry.version == 1: - data = {**config_entry.data} - - entry_updates: dict[str, Any] = {} - if CONF_SCAN_INTERVAL in config_entry.data: - entry_updates["data"] = data - entry_updates["options"] = { - **config_entry.options, - CONF_SCAN_INTERVAL: data.pop(CONF_SCAN_INTERVAL), + + update_data = {**config_entry.data} + update_options = {**config_entry.options} + + if CONF_SCAN_INTERVAL in update_data: + update_options = { + **update_options, + CONF_SCAN_INTERVAL: update_data.pop(CONF_SCAN_INTERVAL), } - if entry_updates: - hass.config_entries.async_update_entry(config_entry, **entry_updates) - start_device_id = data.pop(ConfName.DEVICE_ID) - number_of_inverters = data.pop(ConfName.NUMBER_INVERTERS) + start_device_id = update_data.pop(ConfName.DEVICE_ID) + number_of_inverters = update_data.pop(ConfName.NUMBER_INVERTERS) inverter_list = [] for inverter_index in range(number_of_inverters): inverter_unit_id = inverter_index + start_device_id inverter_list.append(inverter_unit_id) - data["data"] = { - **config_entry.data, + update_data = { + **update_data, ConfName.DEVICE_LIST: inverter_list, } hass.config_entries.async_update_entry( - config_entry, data=data["data"], version=2, minor_version=0 + config_entry, + data=update_data, + options=update_options, + version=2, + minor_version=0, ) _LOGGER.warning( - f"Migrated config to version {config_entry.version}.{config_entry.minor_version}" + f"Migrated to version {config_entry.version}.{config_entry.minor_version}" ) return True From 5aaddc541532f68df0ab356ecc4e2aade0a96d49 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:21:58 -0700 Subject: [PATCH 15/30] Update reconfigure to support device list --- .../solaredge_modbus_multi/config_flow.py | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index caa3a79e..2d7e9558 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -62,7 +62,6 @@ async def async_step_user( inverter_count = len( device_list_from_string(user_input[ConfName.DEVICE_LIST]) ) - except HomeAssistantError as e: errors[ConfName.DEVICE_LIST] = f"{e}" @@ -124,48 +123,53 @@ async def async_step_reconfigure( config_entry = self.hass.config_entries.async_get_entry( self.context["entry_id"] ) - assert config_entry - unique_id = config_entry.unique_id if user_input is not None: user_input[CONF_HOST] = user_input[CONF_HOST].lower() + user_input[ConfName.DEVICE_LIST] = re.sub( + r"\s+", "", user_input[ConfName.DEVICE_LIST], flags=re.UNICODE + ) - if not host_valid(user_input[CONF_HOST]): - errors[CONF_HOST] = "invalid_host" - elif user_input[CONF_PORT] < 1: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[CONF_PORT] > 65535: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[ConfName.DEVICE_ID] > 247: - errors[ConfName.DEVICE_ID] = "max_device_id" - elif user_input[ConfName.DEVICE_ID] < 1: - errors[ConfName.DEVICE_ID] = "min_device_id" - elif user_input[ConfName.NUMBER_INVERTERS] > 32: - errors[ConfName.NUMBER_INVERTERS] = "max_inverters" - elif user_input[ConfName.NUMBER_INVERTERS] < 1: - errors[ConfName.NUMBER_INVERTERS] = "min_inverters" - elif ( - user_input[ConfName.NUMBER_INVERTERS] + user_input[ConfName.DEVICE_ID] - > 247 - ): - errors[ConfName.NUMBER_INVERTERS] = "too_many_inverters" - else: - return self.async_update_reload_and_abort( - config_entry, - unique_id=unique_id, - data={**config_entry.data, **user_input}, - reason="reconfigure_successful", + try: + inverter_count = len( + device_list_from_string(user_input[ConfName.DEVICE_LIST]) ) + except HomeAssistantError as e: + errors[ConfName.DEVICE_LIST] = f"{e}" + + else: + if not host_valid(user_input[CONF_HOST]): + errors[CONF_HOST] = "invalid_host" + elif 1 < user_input[CONF_PORT] > 65535: + errors[CONF_PORT] = "invalid_tcp_port" + elif inverter_count > 32: + errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" + elif inverter_count < 1: + errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" + else: + + user_input[ConfName.DEVICE_LIST] = device_list_from_string( + user_input[ConfName.DEVICE_LIST] + ) + + return self.async_update_reload_and_abort( + config_entry, + unique_id=config_entry.unique_id, + data={**config_entry.data, **user_input}, + reason="reconfigure_successful", + ) else: + reconfig_device_list = ",".join( + str(device) + for device in config_entry.data.get( + ConfName.DEVICE_LIST, ConfDefaultStr.DEVICE_LIST + ) + ) + user_input = { CONF_HOST: config_entry.data.get(CONF_HOST), CONF_PORT: config_entry.data.get(CONF_PORT, ConfDefaultInt.PORT), - ConfName.NUMBER_INVERTERS: config_entry.data.get( - ConfName.NUMBER_INVERTERS, ConfDefaultInt.NUMBER_INVERTERS - ), - ConfName.DEVICE_ID: config_entry.data.get( - ConfName.DEVICE_ID, ConfDefaultInt.DEVICE_ID - ), + ConfName.DEVICE_LIST: reconfig_device_list, } return self.async_show_form( @@ -177,12 +181,9 @@ async def async_step_reconfigure( int ), vol.Required( - f"{ConfName.NUMBER_INVERTERS}", - default=user_input[ConfName.NUMBER_INVERTERS], - ): vol.Coerce(int), - vol.Required( - f"{ConfName.DEVICE_ID}", default=user_input[ConfName.DEVICE_ID] - ): vol.Coerce(int), + f"{ConfName.DEVICE_LIST}", + default=user_input[ConfName.DEVICE_LIST], + ): cv.string, }, ), errors=errors, From be55ae4f008cf808d660858914806bed0275d12c Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:28:28 -0700 Subject: [PATCH 16/30] Update translations --- custom_components/solaredge_modbus_multi/strings.json | 6 +++--- .../solaredge_modbus_multi/translations/de.json | 8 ++++---- .../solaredge_modbus_multi/translations/en.json | 6 +++--- .../solaredge_modbus_multi/translations/fr.json | 8 ++++---- .../solaredge_modbus_multi/translations/it.json | 8 ++++---- .../solaredge_modbus_multi/translations/nb.json | 8 ++++---- .../solaredge_modbus_multi/translations/nl.json | 8 ++++---- .../solaredge_modbus_multi/translations/pl.json | 8 ++++---- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index 2ea8a787..1c2842f5 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -15,8 +15,7 @@ "data": { "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535.", "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", - "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID." + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.", + "empty_device_id": "The ID list contains an empty or undefined value." }, "abort": { "already_configured": "Device is already configured", diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index d7d22eee..b739b5b5 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -7,7 +7,7 @@ "name": "Sensorpräfix", "host": "Wechselrichter-IP-Adresse", "port": "Modbus/TCP-Port", - "device_id": "Wechselrichter-Modbus-Adresse (Geräte-ID)" + "device_list": "Liste der Wechselrichter-Geräte-IDs" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "Wechselrichter-IP-Adresse", "port": "Modbus/TCP-Port", - "device_id": "Wechselrichter-Modbus-Adresse (Geräte-ID)", - "number_of_inverters": "Anzahl Wechselrichter" + "device_list": "Liste der Wechselrichter-Geräte-IDs" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Ungültige IP-Adresse.", "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535.", "invalid_range_format": "Der Eintrag sieht aus wie ein Bereich, es ist jedoch nur ein „-“ pro Bereich zulässig.", - "invalid_range_lte": "Die Start-ID in einem Bereich muss kleiner oder gleich der End-ID sein." + "invalid_range_lte": "Die Start-ID in einem Bereich muss kleiner oder gleich der End-ID sein.", + "empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert." }, "abort": { "already_configured": "Gerät ist bereits konfiguriert", diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index 2ea8a787..1c2842f5 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -15,8 +15,7 @@ "data": { "host": "Inverter IP Address", "port": "Modbus/TCP Port", - "device_id": "Inverter Modbus Address (Device ID)", - "number_of_inverters": "Number of Inverters" + "device_list": "Inverter Device ID List" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Invalid IP address.", "invalid_tcp_port": "Valid port range is 1 to 65535.", "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", - "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID." + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.", + "empty_device_id": "The ID list contains an empty or undefined value." }, "abort": { "already_configured": "Device is already configured", diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index 3ab0d761..8a472d16 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -7,7 +7,7 @@ "name": "Prefix du capteur", "host": "Adresse IP de l'onduleur", "port": "Port Modbus/TCP", - "device_id": "L'adresse Modbus de l'onduleur (Device ID)" + "device_list": "Liste des ID des appareils de l'onduleur" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "Adresse IP de l'onduleur", "port": "Port Modbus/TCP", - "device_id": "L'adresse Modbus de l'onduleur (Device ID)", - "number_of_inverters": "Nombre d'onduleurs" + "device_list": "Liste des ID des appareils de l'onduleur" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Adresse IP invalide.", "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535.", "invalid_range_format": "L'entrée ressemble à une plage mais un seul « - » par plage est autorisé.", - "invalid_range_lte": "L’ID de début d’une plage doit être inférieur ou égal à l’ID de fin." + "invalid_range_lte": "L’ID de début d’une plage doit être inférieur ou égal à l’ID de fin.", + "empty_device_id": "La liste d'ID contient une valeur vide ou non définie." }, "abort": { "already_configured": "L'appareil est déjà configuré", diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 6047239d..48ac93d1 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -7,7 +7,7 @@ "name": "Prefisso sensore", "host": "Indirizzo IP dell'inverter", "port": "Porta Modbus/TCP", - "device_id": "Indirizzo Modbus dell'inverter (ID dispositivo)" + "device_list": "Elenco ID dispositivi inverter" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "Indirizzo IP dell'inverter", "port": "Porta Modbus/TCP", - "device_id": "Indirizzo Modbus dell'inverter (ID dispositivo)", - "number_of_inverters": "Numero di inverter" + "device_list": "Elenco ID dispositivi inverter" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Indirizzo IP non valido.", "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535.", "invalid_range_format": "L'immissione sembra un intervallo ma è consentito solo un '-' per intervallo.", - "invalid_range_lte": "L'ID iniziale in un intervallo deve essere inferiore o uguale all'ID finale." + "invalid_range_lte": "L'ID iniziale in un intervallo deve essere inferiore o uguale all'ID finale.", + "empty_device_id": "L'elenco ID contiene un valore vuoto o non definito." }, "abort": { "already_configured": "Il dispositivo è già configurato", diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index 94131418..ab09abb0 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -7,7 +7,7 @@ "name": "Sensorvoorvoegsel", "host": "IP-adres van omvormer", "port": "Modbus/TCP-poort", - "device_id": "Inverter Modbus-adresse (enhets-ID)" + "device_list": "Inverter-enhetsliste" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "IP-adres van omvormer", "port": "Modbus/TCP-poort", - "device_id": "Inverter Modbus-adresse (enhets-ID)", - "number_of_inverters": "Antall omformere koblet sammen" + "device_list": "Inverter-enhetsliste" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Ugyldig IP-adresse.", "invalid_tcp_port": "Gyldig portområde er 1 til 65535.", "invalid_range_format": "Oppføring ser ut som et område, men bare én '-' per område er tillatt.", - "invalid_range_lte": "Start-ID i et område må være mindre enn eller lik slutt-ID." + "invalid_range_lte": "Start-ID i et område må være mindre enn eller lik slutt-ID.", + "empty_device_id": "ID-listen inneholder en tom eller udefinert verdi." }, "abort": { "already_configured": "Enheten er allerede konfigurert", diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 70573c7f..43d8c809 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -7,7 +7,7 @@ "name": "Sensor prefix", "host": "omvormer IP-adres", "port": "Modbus/TCP Port", - "device_id": "Omvormer Modbus-adres (apparaat-ID)" + "device_list": "Omvormerapparaat-ID-lijst" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "omvormer IP-adres", "port": "Modbus/TCP Port", - "device_id": "Omvormer Modbus-adres (apparaat-ID)", - "number_of_inverters": "Aantal aangesloten omvormers" + "device_list": "Omvormerapparaat-ID-lijst" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Ongeldig IP-adres.", "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535.", "invalid_range_format": "Invoer ziet eruit als een bereik, maar er is slechts één '-' per bereik toegestaan.", - "invalid_range_lte": "De start-ID in een bereik moet kleiner zijn dan of gelijk zijn aan de eind-ID." + "invalid_range_lte": "De start-ID in een bereik moet kleiner zijn dan of gelijk zijn aan de eind-ID.", + "empty_device_id": "De ID-lijst bevat een lege of ongedefinieerde waarde." }, "abort": { "already_configured": "Apparaat is al geconfigureerd", diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index 054f6264..f8e1f1ba 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -7,7 +7,7 @@ "name": "Prefix sensora", "host": "Adres IP inwertera", "port": "Modbus/TCP Port", - "device_id": "Adres Modbus Inwertera (Device ID)" + "device_list": "Lista identyfikatorów urządzeń falownika" } }, "reconfigure": { @@ -15,8 +15,7 @@ "data": { "host": "Adres IP inwertera", "port": "Modbus/TCP Port", - "device_id": "Adres Modbus Inwertera (Device ID)", - "number_of_inverters": "Ilość inwerterów" + "device_list": "Lista identyfikatorów urządzeń falownika" } } }, @@ -27,7 +26,8 @@ "invalid_host": "Błędny adres IP.", "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535.", "invalid_range_format": "Wpis wygląda jak zakres, ale dozwolony jest tylko jeden znak „-” na zakres.", - "invalid_range_lte": "Początkowy identyfikator w zakresie musi być mniejszy lub równy identyfikatorowi końcowemu." + "invalid_range_lte": "Początkowy identyfikator w zakresie musi być mniejszy lub równy identyfikatorowi końcowemu.", + "empty_device_id": "Lista identyfikatorów zawiera pustą lub niezdefiniowaną wartość." }, "abort": { "already_configured": "Urządzenie jest już skonfigurowane", From 0ca792cdee03a7c6c6f8565464b734802cd8cce1 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:05:34 -0700 Subject: [PATCH 17/30] Interval comparisons for easier reading --- .../solaredge_modbus_multi/config_flow.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 2d7e9558..890a5ec7 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -70,13 +70,9 @@ async def async_step_user( errors[CONF_HOST] = "invalid_host" elif user_input[CONF_HOST] in solaredge_modbus_multi_entries(self.hass): errors[CONF_HOST] = "already_configured" - elif user_input[CONF_PORT] < 1: + elif not 1 <= user_input[CONF_PORT] <= 65535: errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[CONF_PORT] > 65535: - errors[CONF_PORT] = "invalid_tcp_port" - elif inverter_count > 32: - errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" - elif inverter_count < 1: + elif not 1 <= inverter_count <= 32: errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" else: await self.async_set_unique_id(user_input[CONF_HOST]) @@ -140,11 +136,9 @@ async def async_step_reconfigure( else: if not host_valid(user_input[CONF_HOST]): errors[CONF_HOST] = "invalid_host" - elif 1 < user_input[CONF_PORT] > 65535: + elif not 1 <= user_input[CONF_PORT] <= 65535: errors[CONF_PORT] = "invalid_tcp_port" - elif inverter_count > 32: - errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" - elif inverter_count < 1: + elif not 1 <= inverter_count <= 32: errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" else: From 4d7d3c3e8a869b904b4e9fdaac09694e686f3d0d Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:06:32 -0700 Subject: [PATCH 18/30] Inverter list support in repair issue --- .../solaredge_modbus_multi/repairs.py | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/repairs.py b/custom_components/solaredge_modbus_multi/repairs.py index 84ff2640..95d750fe 100644 --- a/custom_components/solaredge_modbus_multi/repairs.py +++ b/custom_components/solaredge_modbus_multi/repairs.py @@ -2,6 +2,7 @@ from __future__ import annotations +import re from typing import cast import homeassistant.helpers.config_validation as cv @@ -11,9 +12,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError -from .const import ConfName -from .helpers import host_valid +from .const import ConfDefaultStr, ConfName +from .helpers import device_list_from_string, host_valid class CheckConfigurationRepairFlow(RepairsFlow): @@ -41,37 +43,42 @@ async def async_step_confirm( if user_input is not None: user_input[CONF_HOST] = user_input[CONF_HOST].lower() + user_input[ConfName.DEVICE_LIST] = re.sub( + r"\s+", "", user_input[ConfName.DEVICE_LIST], flags=re.UNICODE + ) - if not host_valid(user_input[CONF_HOST]): - errors[CONF_HOST] = "invalid_host" - elif user_input[CONF_PORT] < 1: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[CONF_PORT] > 65535: - errors[CONF_PORT] = "invalid_tcp_port" - elif user_input[ConfName.DEVICE_ID] > 247: - errors[ConfName.DEVICE_ID] = "invalid_device_id" - elif user_input[ConfName.DEVICE_ID] < 1: - errors[ConfName.DEVICE_ID] = "min_device_id" - elif user_input[ConfName.NUMBER_INVERTERS] > 32: - errors[ConfName.NUMBER_INVERTERS] = "max_inverters" - elif user_input[ConfName.NUMBER_INVERTERS] < 1: - errors[ConfName.NUMBER_INVERTERS] = "min_inverters" - elif ( - user_input[ConfName.NUMBER_INVERTERS] + user_input[ConfName.DEVICE_ID] - > 247 - ): - errors[ConfName.NUMBER_INVERTERS] = "too_many_inverters" - else: - self.hass.config_entries.async_update_entry( - self._entry, data={**self._entry.data, **user_input} + try: + inverter_count = len( + device_list_from_string(user_input[ConfName.DEVICE_LIST]) ) - return self.async_create_entry(title="", data={}) + except HomeAssistantError as e: + errors[ConfName.DEVICE_LIST] = f"{e}" + + else: + if not host_valid(user_input[CONF_HOST]): + errors[CONF_HOST] = "invalid_host" + elif not 1 <= user_input[CONF_PORT] <= 65535: + errors[CONF_PORT] = "invalid_tcp_port" + elif not 1 <= inverter_count <= 32: + errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" + else: + self.hass.config_entries.async_update_entry( + self._entry, data={**self._entry.data, **user_input} + ) + return self.async_create_entry(title="", data={}) + else: + reconfig_device_list = ",".join( + str(device) + for device in self._entry.data.get( + ConfName.DEVICE_LIST, ConfDefaultStr.DEVICE_LIST + ) + ) + user_input = { CONF_HOST: self._entry.data[CONF_HOST], CONF_PORT: self._entry.data[CONF_PORT], - ConfName.NUMBER_INVERTERS: self._entry.data[ConfName.NUMBER_INVERTERS], - ConfName.DEVICE_ID: self._entry.data[ConfName.DEVICE_ID], + ConfName.DEVICE_LIST: reconfig_device_list, } return self.async_show_form( @@ -83,12 +90,9 @@ async def async_step_confirm( int ), vol.Required( - f"{ConfName.NUMBER_INVERTERS}", - default=user_input[ConfName.NUMBER_INVERTERS], - ): vol.Coerce(int), - vol.Required( - f"{ConfName.DEVICE_ID}", default=user_input[ConfName.DEVICE_ID] - ): vol.Coerce(int), + f"{ConfName.DEVICE_LIST}", + default=user_input[ConfName.DEVICE_LIST], + ): cv.string, } ), errors=errors, From f9fdfbcb1a52dc03adfa99c8f04d0fecfc4fe9c2 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:06:39 -0700 Subject: [PATCH 19/30] Update translations --- custom_components/solaredge_modbus_multi/strings.json | 5 ++++- .../solaredge_modbus_multi/translations/de.json | 5 ++++- .../solaredge_modbus_multi/translations/en.json | 5 ++++- .../solaredge_modbus_multi/translations/fr.json | 5 ++++- .../solaredge_modbus_multi/translations/it.json | 5 ++++- .../solaredge_modbus_multi/translations/nb.json | 5 ++++- .../solaredge_modbus_multi/translations/nl.json | 5 ++++- .../solaredge_modbus_multi/translations/pl.json | 5 ++++- 8 files changed, 32 insertions(+), 8 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index 1c2842f5..1c737acb 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -90,7 +90,10 @@ "invalid_device_id": "Device ID must be between 1 to 247.", "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", - "invalid_tcp_port": "Valid port range is 1 to 65535." + "invalid_tcp_port": "Valid port range is 1 to 65535.", + "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.", + "empty_device_id": "The ID list contains an empty or undefined value." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index b739b5b5..7a8adeda 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -91,7 +91,10 @@ "invalid_device_id": "Die Geräte-ID muss zwischen 1 und 247 liegen.", "invalid_inverter_count": "Muss zwischen 1 und 32 Wechselrichtern liegen.", "invalid_host": "Ungültige IP-Adresse.", - "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535." + "invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535.", + "invalid_range_format": "Der Eintrag sieht aus wie ein Bereich, es ist jedoch nur ein „-“ pro Bereich zulässig.", + "invalid_range_lte": "Die Start-ID in einem Bereich muss kleiner oder gleich der End-ID sein.", + "empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index 1c2842f5..1c737acb 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -90,7 +90,10 @@ "invalid_device_id": "Device ID must be between 1 to 247.", "invalid_inverter_count": "Must be between 1 to 32 inverters.", "invalid_host": "Invalid IP address.", - "invalid_tcp_port": "Valid port range is 1 to 65535." + "invalid_tcp_port": "Valid port range is 1 to 65535.", + "invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.", + "invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.", + "empty_device_id": "The ID list contains an empty or undefined value." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index 8a472d16..d7cd2d6e 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -91,7 +91,10 @@ "invalid_device_id": "L'adresse Modbus doit être entre 1 et 247.", "invalid_inverter_count": "Doit être entre 1 et 32 onduleurs.", "invalid_host": "Adresse IP invalide.", - "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535." + "invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535.", + "invalid_range_format": "L'entrée ressemble à une plage mais un seul « - » par plage est autorisé.", + "invalid_range_lte": "L’ID de début d’une plage doit être inférieur ou égal à l’ID de fin.", + "empty_device_id": "La liste d'ID contient une valeur vide ou non définie." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 48ac93d1..444cc055 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -91,7 +91,10 @@ "invalid_device_id": "L'ID del dispositivo deve essere compreso tra 1 e 247.", "invalid_inverter_count": "Deve essere compreso tra 1 e 32 inverter.", "invalid_host": "Indirizzo IP non valido.", - "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535." + "invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535.", + "invalid_range_format": "L'immissione sembra un intervallo ma è consentito solo un '-' per intervallo.", + "invalid_range_lte": "L'ID iniziale in un intervallo deve essere inferiore o uguale all'ID finale.", + "empty_device_id": "L'elenco ID contiene un valore vuoto o non definito." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index ab09abb0..a39f81c9 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -91,7 +91,10 @@ "invalid_device_id": "Enhets-ID må være mellom 1 og 247.", "invalid_inverter_count": "Må være mellom 1 og 32 omformere.", "invalid_host": "Ugyldig IP-adresse.", - "invalid_tcp_port": "Gyldig portområde er 1 til 65535." + "invalid_tcp_port": "Gyldig portområde er 1 til 65535.", + "invalid_range_format": "Oppføring ser ut som et område, men bare én '-' per område er tillatt.", + "invalid_range_lte": "Start-ID i et område må være mindre enn eller lik slutt-ID.", + "empty_device_id": "ID-listen inneholder en tom eller udefinert verdi." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 43d8c809..21bbf9d2 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -91,7 +91,10 @@ "invalid_device_id": "Apparaat-ID moet tussen 1 en 247 liggen.", "invalid_inverter_count": "Moet tussen 1 en 32 omvormers zijn.", "invalid_host": "Ongeldig IP-adres.", - "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535." + "invalid_tcp_port": "Geldig poortbereik is 1 tot 65535.", + "invalid_range_format": "Invoer ziet eruit als een bereik, maar er is slechts één '-' per bereik toegestaan.", + "invalid_range_lte": "De start-ID in een bereik moet kleiner zijn dan of gelijk zijn aan de eind-ID.", + "empty_device_id": "De ID-lijst bevat een lege of ongedefinieerde waarde." } } } diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index f8e1f1ba..8a36c8bd 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -91,7 +91,10 @@ "invalid_device_id": "Device ID musi być pomiędzy 1 i 247.", "invalid_inverter_count": "Dopuszczalna liczba inwerterów to od 1 do 32.", "invalid_host": "Błędny adres IP.", - "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535." + "invalid_tcp_port": "Dozwolony zakres portów to od 1 do 65535.", + "invalid_range_format": "Wpis wygląda jak zakres, ale dozwolony jest tylko jeden znak „-” na zakres.", + "invalid_range_lte": "Początkowy identyfikator w zakresie musi być mniejszy lub równy identyfikatorowi końcowemu.", + "empty_device_id": "Lista identyfikatorów zawiera pustą lub niezdefiniowaną wartość." } } } From 78c3417b172691018903fd1463a1a64b1343c723 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:12:16 -0700 Subject: [PATCH 20/30] Helper functions contributed by @thargy Co-Authored-By: Craig Dean <1908506+thargy@users.noreply.github.com> --- custom_components/solaredge_modbus_multi/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/solaredge_modbus_multi/helpers.py b/custom_components/solaredge_modbus_multi/helpers.py index 544a8d61..e0f44a97 100644 --- a/custom_components/solaredge_modbus_multi/helpers.py +++ b/custom_components/solaredge_modbus_multi/helpers.py @@ -64,6 +64,7 @@ def device_list_from_string(value: str) -> list[int]: Credit: https://github.com/thargy/modbus-scanner/blob/main/scan.py """ + parts = [p.strip() for p in value.split(",")] ids = [] for p in parts: From 9910d4506dc04a53402c12f4eff6d90716b21d32 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sat, 27 Jul 2024 10:10:52 -0700 Subject: [PATCH 21/30] Major version bump Config is backwards incompatible with 2.x.x releases. --- custom_components/solaredge_modbus_multi/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/solaredge_modbus_multi/manifest.json b/custom_components/solaredge_modbus_multi/manifest.json index 2f6fbea3..6f351342 100644 --- a/custom_components/solaredge_modbus_multi/manifest.json +++ b/custom_components/solaredge_modbus_multi/manifest.json @@ -10,5 +10,5 @@ "issue_tracker": "https://github.com/WillCodeForCats/solaredge-modbus-multi/issues", "loggers": ["custom_components.solaredge_modbus_multi"], "requirements": ["pymodbus>=3.6.6"], - "version": "2.4.18" + "version": "3.0.0-pre.1" } From 79913e124c43eadc9c61abad416dde1d0a0637ea Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:05:38 -0700 Subject: [PATCH 22/30] Update repairs.py --- custom_components/solaredge_modbus_multi/repairs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/solaredge_modbus_multi/repairs.py b/custom_components/solaredge_modbus_multi/repairs.py index 95d750fe..793dfb3e 100644 --- a/custom_components/solaredge_modbus_multi/repairs.py +++ b/custom_components/solaredge_modbus_multi/repairs.py @@ -62,6 +62,10 @@ async def async_step_confirm( elif not 1 <= inverter_count <= 32: errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" else: + user_input[ConfName.DEVICE_LIST] = device_list_from_string( + user_input[ConfName.DEVICE_LIST] + ) + self.hass.config_entries.async_update_entry( self._entry, data={**self._entry.data, **user_input} ) From 1d4a629e8c50b913e02e8deb1a895ef02ece24bc Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:09:20 -0700 Subject: [PATCH 23/30] Update config_flow.py --- custom_components/solaredge_modbus_multi/config_flow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 890a5ec7..e2d20d97 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -76,6 +76,7 @@ async def async_step_user( errors[ConfName.DEVICE_LIST] = "invalid_inverter_count" else: await self.async_set_unique_id(user_input[CONF_HOST]) + self._abort_if_unique_id_configured() user_input[ConfName.DEVICE_LIST] = device_list_from_string( From 5444c4476aaff842f32ca031a0ecb96234c5c172 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:09:22 -0700 Subject: [PATCH 24/30] Update repairs.py --- custom_components/solaredge_modbus_multi/repairs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/solaredge_modbus_multi/repairs.py b/custom_components/solaredge_modbus_multi/repairs.py index 793dfb3e..6958c114 100644 --- a/custom_components/solaredge_modbus_multi/repairs.py +++ b/custom_components/solaredge_modbus_multi/repairs.py @@ -69,6 +69,7 @@ async def async_step_confirm( self.hass.config_entries.async_update_entry( self._entry, data={**self._entry.data, **user_input} ) + return self.async_create_entry(title="", data={}) else: From 0968f33d009d29f6e2998fa2bc6de6d52376c098 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:16:07 -0700 Subject: [PATCH 25/30] Add config step for auto or manual setup --- .../solaredge_modbus_multi/config_flow.py | 65 ++++++++++++++++--- .../solaredge_modbus_multi/const.py | 5 ++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index e2d20d97..5df9ba4c 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -8,15 +8,18 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol from homeassistant import config_entries -from homeassistant.config_entries import ConfigEntry, OptionsFlow +from homeassistant.config_entries import ConfigEntry, ConfigFlowResult, OptionsFlow from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SCAN_INTERVAL from homeassistant.core import HomeAssistant, callback -from homeassistant.data_entry_flow import FlowResult from homeassistant.exceptions import HomeAssistantError from .const import ( DEFAULT_NAME, DOMAIN, + SETUP_MANUAL, + SETUP_SCAN, + SETUP_SCAN_FULL, + SETUP_TYPE, ConfDefaultFlag, ConfDefaultInt, ConfDefaultStr, @@ -48,8 +51,52 @@ def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow: async def async_step_user( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: - """Handle the initial config flow step.""" + ) -> ConfigFlowResult: + """Handle the initial step.""" + data_schema = vol.Schema( + { + vol.Required(SETUP_TYPE, default=SETUP_SCAN): vol.In( + ( + SETUP_SCAN, + SETUP_SCAN_FULL, + SETUP_MANUAL, + ) + ) + } + ) + + if user_input is None: + return self.async_show_form( + step_id="user", + data_schema=data_schema, + ) + + if user_input[SETUP_TYPE] == SETUP_MANUAL: + return await self.async_step_manual() + if user_input[SETUP_TYPE] == SETUP_SCAN_FULL: + return await self.async_step_scan_full() + return await self.async_step_scan() + + async def async_step_scan( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle the scan config flow step.""" + errors = {} + + raise HomeAssistantError("async_step_scan") + + async def async_step_scan_full( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle the full scan config flow step.""" + errors = {} + + raise HomeAssistantError("async_step_scan_full") + + async def async_step_manual( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle the manual config flow step.""" errors = {} if user_input is not None: @@ -95,7 +142,7 @@ async def async_step_user( } return self.async_show_form( - step_id="user", + step_id="manual", data_schema=vol.Schema( { vol.Optional(CONF_NAME, default=user_input[CONF_NAME]): cv.string, @@ -114,7 +161,7 @@ async def async_step_user( async def async_step_reconfigure( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: + ) -> ConfigFlowResult: """Handle the reconfigure flow step.""" errors = {} config_entry = self.hass.config_entries.async_get_entry( @@ -194,7 +241,7 @@ def __init__(self, config_entry: ConfigEntry): async def async_step_init( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: + ) -> ConfigFlowResult: """Handle the initial options flow step.""" errors = {} @@ -283,7 +330,7 @@ async def async_step_init( async def async_step_battery_options( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: + ) -> ConfigFlowResult: """Battery Options""" errors = {} @@ -340,7 +387,7 @@ async def async_step_battery_options( async def async_step_adv_pwr_ctl( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: + ) -> ConfigFlowResult: """Power Control Options""" errors = {} diff --git a/custom_components/solaredge_modbus_multi/const.py b/custom_components/solaredge_modbus_multi/const.py index c4f5715c..418bd7e6 100644 --- a/custom_components/solaredge_modbus_multi/const.py +++ b/custom_components/solaredge_modbus_multi/const.py @@ -9,6 +9,11 @@ DOMAIN = "solaredge_modbus_multi" DEFAULT_NAME = "SolarEdge" +SETUP_TYPE = "setup_type" +SETUP_SCAN = "Scanning Setup" # Scan IDs 1-32 +SETUP_SCAN_FULL = "Scanning Setup (Full)" # Scan IDs 1-247 +SETUP_MANUAL = "Manual Setup" + # units missing in homeassistant core ENERGY_VOLT_AMPERE_HOUR: Final = "VAh" ENERGY_VOLT_AMPERE_REACTIVE_HOUR: Final = "varh" From d97954d545b13e189b3e92c19193e8f13762f5eb Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:20:30 -0700 Subject: [PATCH 26/30] Update translations --- custom_components/solaredge_modbus_multi/strings.json | 6 ++++++ .../solaredge_modbus_multi/translations/de.json | 6 ++++++ .../solaredge_modbus_multi/translations/en.json | 6 ++++++ .../solaredge_modbus_multi/translations/fr.json | 6 ++++++ .../solaredge_modbus_multi/translations/it.json | 6 ++++++ .../solaredge_modbus_multi/translations/nb.json | 6 ++++++ .../solaredge_modbus_multi/translations/nl.json | 6 ++++++ .../solaredge_modbus_multi/translations/pl.json | 6 ++++++ 8 files changed, 48 insertions(+) diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index 1c737acb..b13a1c3b 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "SolarEdge Modbus Configuration", + "data": { + "setup_type": "Choose a Setup Method" + } + }, + "manual": { + "title": "Manual Modbus Configuration", "data": { "name": "Sensor Prefix", "host": "Inverter IP Address", diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index 7a8adeda..5d754b5b 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "SolarEdge Modbus-Konfiguration", + "data": { + "setup_type": "Wählen Sie eine Einrichtungsmethode" + } + }, + "manual": { + "title": "Manuelle Modbus-Konfiguration", "data": { "name": "Sensorpräfix", "host": "Wechselrichter-IP-Adresse", diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index 1c737acb..b13a1c3b 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "SolarEdge Modbus Configuration", + "data": { + "setup_type": "Choose a Setup Method" + } + }, + "manual": { + "title": "Manual Modbus Configuration", "data": { "name": "Sensor Prefix", "host": "Inverter IP Address", diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index d7cd2d6e..126154bf 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "Configuration SolarEdge Modbus", + "data": { + "setup_type": "Choisissez une méthode de configuration" + } + }, + "manual": { + "title": "Configuration Modbus manuelle", "data": { "name": "Prefix du capteur", "host": "Adresse IP de l'onduleur", diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 444cc055..7b0bc985 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "Configurazione Modbus SolarEdge", + "data": { + "setup_type": "Scegli un metodo di configurazione" + } + }, + "manual": { + "title": "Configurazione Modbus manuale", "data": { "name": "Prefisso sensore", "host": "Indirizzo IP dell'inverter", diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index a39f81c9..fe84b33b 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "SolarEdge Modbus-konfigurasjon", + "data": { + "setup_type": "Velg en oppsettmetode" + } + }, + "manual": { + "title": "Manuell Modbus-konfigurasjon", "data": { "name": "Sensorvoorvoegsel", "host": "IP-adres van omvormer", diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 21bbf9d2..53c9ffa2 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "SolarEdge Modbus-configuratie", + "data": { + "setup_type": "Kies een installatiemethode" + } + }, + "manual": { + "title": "Handmatige Modbus-configuratie", "data": { "name": "Sensor prefix", "host": "omvormer IP-adres", diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index 8a36c8bd..1a6a332d 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -3,6 +3,12 @@ "step": { "user": { "title": "Konfiguracja SolarEdge Modbus", + "data": { + "setup_type": "Wybierz metodę konfiguracji" + } + }, + "manual": { + "title": "Ręczna konfiguracja Modbus", "data": { "name": "Prefix sensora", "host": "Adres IP inwertera", From d858c12449f766833fcd2e3eb6e836f7c0891a95 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:22:15 -0700 Subject: [PATCH 27/30] Revert "Add config step for auto or manual setup" This reverts commit 0968f33d009d29f6e2998fa2bc6de6d52376c098. --- .../solaredge_modbus_multi/config_flow.py | 65 +++---------------- .../solaredge_modbus_multi/const.py | 5 -- 2 files changed, 9 insertions(+), 61 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/config_flow.py b/custom_components/solaredge_modbus_multi/config_flow.py index 5df9ba4c..e2d20d97 100644 --- a/custom_components/solaredge_modbus_multi/config_flow.py +++ b/custom_components/solaredge_modbus_multi/config_flow.py @@ -8,18 +8,15 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol from homeassistant import config_entries -from homeassistant.config_entries import ConfigEntry, ConfigFlowResult, OptionsFlow +from homeassistant.config_entries import ConfigEntry, OptionsFlow from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SCAN_INTERVAL from homeassistant.core import HomeAssistant, callback +from homeassistant.data_entry_flow import FlowResult from homeassistant.exceptions import HomeAssistantError from .const import ( DEFAULT_NAME, DOMAIN, - SETUP_MANUAL, - SETUP_SCAN, - SETUP_SCAN_FULL, - SETUP_TYPE, ConfDefaultFlag, ConfDefaultInt, ConfDefaultStr, @@ -51,52 +48,8 @@ def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow: async def async_step_user( self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: - """Handle the initial step.""" - data_schema = vol.Schema( - { - vol.Required(SETUP_TYPE, default=SETUP_SCAN): vol.In( - ( - SETUP_SCAN, - SETUP_SCAN_FULL, - SETUP_MANUAL, - ) - ) - } - ) - - if user_input is None: - return self.async_show_form( - step_id="user", - data_schema=data_schema, - ) - - if user_input[SETUP_TYPE] == SETUP_MANUAL: - return await self.async_step_manual() - if user_input[SETUP_TYPE] == SETUP_SCAN_FULL: - return await self.async_step_scan_full() - return await self.async_step_scan() - - async def async_step_scan( - self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: - """Handle the scan config flow step.""" - errors = {} - - raise HomeAssistantError("async_step_scan") - - async def async_step_scan_full( - self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: - """Handle the full scan config flow step.""" - errors = {} - - raise HomeAssistantError("async_step_scan_full") - - async def async_step_manual( - self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: - """Handle the manual config flow step.""" + ) -> FlowResult: + """Handle the initial config flow step.""" errors = {} if user_input is not None: @@ -142,7 +95,7 @@ async def async_step_manual( } return self.async_show_form( - step_id="manual", + step_id="user", data_schema=vol.Schema( { vol.Optional(CONF_NAME, default=user_input[CONF_NAME]): cv.string, @@ -161,7 +114,7 @@ async def async_step_manual( async def async_step_reconfigure( self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: + ) -> FlowResult: """Handle the reconfigure flow step.""" errors = {} config_entry = self.hass.config_entries.async_get_entry( @@ -241,7 +194,7 @@ def __init__(self, config_entry: ConfigEntry): async def async_step_init( self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: + ) -> FlowResult: """Handle the initial options flow step.""" errors = {} @@ -330,7 +283,7 @@ async def async_step_init( async def async_step_battery_options( self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: + ) -> FlowResult: """Battery Options""" errors = {} @@ -387,7 +340,7 @@ async def async_step_battery_options( async def async_step_adv_pwr_ctl( self, user_input: dict[str, Any] | None = None - ) -> ConfigFlowResult: + ) -> FlowResult: """Power Control Options""" errors = {} diff --git a/custom_components/solaredge_modbus_multi/const.py b/custom_components/solaredge_modbus_multi/const.py index 418bd7e6..c4f5715c 100644 --- a/custom_components/solaredge_modbus_multi/const.py +++ b/custom_components/solaredge_modbus_multi/const.py @@ -9,11 +9,6 @@ DOMAIN = "solaredge_modbus_multi" DEFAULT_NAME = "SolarEdge" -SETUP_TYPE = "setup_type" -SETUP_SCAN = "Scanning Setup" # Scan IDs 1-32 -SETUP_SCAN_FULL = "Scanning Setup (Full)" # Scan IDs 1-247 -SETUP_MANUAL = "Manual Setup" - # units missing in homeassistant core ENERGY_VOLT_AMPERE_HOUR: Final = "VAh" ENERGY_VOLT_AMPERE_REACTIVE_HOUR: Final = "varh" From b98ebb47fa329141d30c665b901dbb13b3982831 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:22:19 -0700 Subject: [PATCH 28/30] Revert "Update translations" This reverts commit d97954d545b13e189b3e92c19193e8f13762f5eb. --- custom_components/solaredge_modbus_multi/strings.json | 6 ------ .../solaredge_modbus_multi/translations/de.json | 6 ------ .../solaredge_modbus_multi/translations/en.json | 6 ------ .../solaredge_modbus_multi/translations/fr.json | 6 ------ .../solaredge_modbus_multi/translations/it.json | 6 ------ .../solaredge_modbus_multi/translations/nb.json | 6 ------ .../solaredge_modbus_multi/translations/nl.json | 6 ------ .../solaredge_modbus_multi/translations/pl.json | 6 ------ 8 files changed, 48 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/strings.json b/custom_components/solaredge_modbus_multi/strings.json index b13a1c3b..1c737acb 100644 --- a/custom_components/solaredge_modbus_multi/strings.json +++ b/custom_components/solaredge_modbus_multi/strings.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "SolarEdge Modbus Configuration", - "data": { - "setup_type": "Choose a Setup Method" - } - }, - "manual": { - "title": "Manual Modbus Configuration", "data": { "name": "Sensor Prefix", "host": "Inverter IP Address", diff --git a/custom_components/solaredge_modbus_multi/translations/de.json b/custom_components/solaredge_modbus_multi/translations/de.json index 5d754b5b..7a8adeda 100644 --- a/custom_components/solaredge_modbus_multi/translations/de.json +++ b/custom_components/solaredge_modbus_multi/translations/de.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "SolarEdge Modbus-Konfiguration", - "data": { - "setup_type": "Wählen Sie eine Einrichtungsmethode" - } - }, - "manual": { - "title": "Manuelle Modbus-Konfiguration", "data": { "name": "Sensorpräfix", "host": "Wechselrichter-IP-Adresse", diff --git a/custom_components/solaredge_modbus_multi/translations/en.json b/custom_components/solaredge_modbus_multi/translations/en.json index b13a1c3b..1c737acb 100644 --- a/custom_components/solaredge_modbus_multi/translations/en.json +++ b/custom_components/solaredge_modbus_multi/translations/en.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "SolarEdge Modbus Configuration", - "data": { - "setup_type": "Choose a Setup Method" - } - }, - "manual": { - "title": "Manual Modbus Configuration", "data": { "name": "Sensor Prefix", "host": "Inverter IP Address", diff --git a/custom_components/solaredge_modbus_multi/translations/fr.json b/custom_components/solaredge_modbus_multi/translations/fr.json index 126154bf..d7cd2d6e 100644 --- a/custom_components/solaredge_modbus_multi/translations/fr.json +++ b/custom_components/solaredge_modbus_multi/translations/fr.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "Configuration SolarEdge Modbus", - "data": { - "setup_type": "Choisissez une méthode de configuration" - } - }, - "manual": { - "title": "Configuration Modbus manuelle", "data": { "name": "Prefix du capteur", "host": "Adresse IP de l'onduleur", diff --git a/custom_components/solaredge_modbus_multi/translations/it.json b/custom_components/solaredge_modbus_multi/translations/it.json index 7b0bc985..444cc055 100644 --- a/custom_components/solaredge_modbus_multi/translations/it.json +++ b/custom_components/solaredge_modbus_multi/translations/it.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "Configurazione Modbus SolarEdge", - "data": { - "setup_type": "Scegli un metodo di configurazione" - } - }, - "manual": { - "title": "Configurazione Modbus manuale", "data": { "name": "Prefisso sensore", "host": "Indirizzo IP dell'inverter", diff --git a/custom_components/solaredge_modbus_multi/translations/nb.json b/custom_components/solaredge_modbus_multi/translations/nb.json index fe84b33b..a39f81c9 100644 --- a/custom_components/solaredge_modbus_multi/translations/nb.json +++ b/custom_components/solaredge_modbus_multi/translations/nb.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "SolarEdge Modbus-konfigurasjon", - "data": { - "setup_type": "Velg en oppsettmetode" - } - }, - "manual": { - "title": "Manuell Modbus-konfigurasjon", "data": { "name": "Sensorvoorvoegsel", "host": "IP-adres van omvormer", diff --git a/custom_components/solaredge_modbus_multi/translations/nl.json b/custom_components/solaredge_modbus_multi/translations/nl.json index 53c9ffa2..21bbf9d2 100644 --- a/custom_components/solaredge_modbus_multi/translations/nl.json +++ b/custom_components/solaredge_modbus_multi/translations/nl.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "SolarEdge Modbus-configuratie", - "data": { - "setup_type": "Kies een installatiemethode" - } - }, - "manual": { - "title": "Handmatige Modbus-configuratie", "data": { "name": "Sensor prefix", "host": "omvormer IP-adres", diff --git a/custom_components/solaredge_modbus_multi/translations/pl.json b/custom_components/solaredge_modbus_multi/translations/pl.json index 1a6a332d..8a36c8bd 100644 --- a/custom_components/solaredge_modbus_multi/translations/pl.json +++ b/custom_components/solaredge_modbus_multi/translations/pl.json @@ -3,12 +3,6 @@ "step": { "user": { "title": "Konfiguracja SolarEdge Modbus", - "data": { - "setup_type": "Wybierz metodę konfiguracji" - } - }, - "manual": { - "title": "Ręczna konfiguracja Modbus", "data": { "name": "Prefix sensora", "host": "Adres IP inwertera", From 41bcf75e503786b1eae407e3654c889dc8f97538 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:33:07 -0700 Subject: [PATCH 29/30] Update __init__.py --- custom_components/solaredge_modbus_multi/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 3196501e..5becb7d2 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -156,7 +156,7 @@ async def async_remove_config_entry_device( async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Migrate old entry.""" - _LOGGER.debug("Migrating from version {config_entry.version}") + _LOGGER.debug("Migrating from config version {config_entry.version}") if config_entry.version > 1: return False @@ -194,7 +194,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> ) _LOGGER.warning( - f"Migrated to version {config_entry.version}.{config_entry.minor_version}" + f"Migrated to config version {config_entry.version}.{config_entry.minor_version}" ) return True From ff32a77d238dbbaa20369a6e1da2693afcf76874 Mon Sep 17 00:00:00 2001 From: WillCodeForCats <48533968+WillCodeForCats@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:35:38 -0700 Subject: [PATCH 30/30] Update migration log messages --- custom_components/solaredge_modbus_multi/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/custom_components/solaredge_modbus_multi/__init__.py b/custom_components/solaredge_modbus_multi/__init__.py index 5becb7d2..d0334637 100644 --- a/custom_components/solaredge_modbus_multi/__init__.py +++ b/custom_components/solaredge_modbus_multi/__init__.py @@ -156,7 +156,10 @@ async def async_remove_config_entry_device( async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Migrate old entry.""" - _LOGGER.debug("Migrating from config version {config_entry.version}") + _LOGGER.debug( + "Migrating from config version " + f"{config_entry.version}.{config_entry.minor_version}" + ) if config_entry.version > 1: return False @@ -194,7 +197,8 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> ) _LOGGER.warning( - f"Migrated to config version {config_entry.version}.{config_entry.minor_version}" + "Migrated to config version " + f"{config_entry.version}.{config_entry.minor_version}" ) return True