Skip to content

Commit

Permalink
Merge branch 'main' into modbus-string-helper
Browse files Browse the repository at this point in the history
  • Loading branch information
WillCodeForCats committed Feb 3, 2025
2 parents 873e012 + 5f3bfcd commit 3153977
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ After rebooting Home Assistant, this integration can be configured through the i
[WillCodeForCats/solaredge-modbus-multi/wiki](https://github.com/WillCodeForCats/solaredge-modbus-multi/wiki)

### Required Versions
* Home Assistant 2024.9.0 or newer
* Home Assistant 2024.12.0 or newer
* Python 3.11 or newer
* pymodbus 3.6.6 through 3.7.4

Expand Down
29 changes: 27 additions & 2 deletions custom_components/solaredge_modbus_multi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_SCAN_INTERVAL, Platform
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SCAN_INTERVAL, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.typing import ConfigType
Expand Down Expand Up @@ -161,10 +161,11 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
f"{config_entry.version}.{config_entry.minor_version}"
)

if config_entry.version > 1:
if config_entry.version > 2:
return False

if config_entry.version == 1:
_LOGGER.debug("Migrating from version 1")

update_data = {**config_entry.data}
update_options = {**config_entry.options}
Expand Down Expand Up @@ -196,6 +197,30 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
minor_version=0,
)

if config_entry.version == 2 and config_entry.minor_version < 1:
_LOGGER.debug("Migrating from version 2.0")

config_entry_data = {**config_entry.data}

# Use host:port address string as the config entry unique ID.
# This is technically not a valid HA unique ID, but with modbus
# we can't know anything like a serial number per IP since a
# single SE modbus IP could have up to 32 different serial numbers
# and the "leader" modbus unit id can't be known programmatically.

old_unique_id = config_entry.unique_id
new_unique_id = f"{config_entry_data[CONF_HOST]}:{config_entry_data[CONF_PORT]}"

_LOGGER.warning(
"Migrating config entry unique ID from %s to %s",
old_unique_id,
new_unique_id,
)

hass.config_entries.async_update_entry(
config_entry, unique_id=new_unique_id, version=2, minor_version=1
)

_LOGGER.warning(
"Migrated to config version "
f"{config_entry.version}.{config_entry.minor_version}"
Expand Down
22 changes: 14 additions & 8 deletions custom_components/solaredge_modbus_multi/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ class SolaredgeModbusMultiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for SolarEdge Modbus Multi."""

VERSION = 2
MINOR_VERSION = 0
MINOR_VERSION = 1

@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
"""Create the options flow for SolarEdge Modbus Multi."""
return SolaredgeModbusMultiOptionsFlowHandler(config_entry)
return SolaredgeModbusMultiOptionsFlowHandler()

async def async_step_user(
self, user_input: dict[str, Any] | None = None
Expand Down Expand Up @@ -84,7 +84,8 @@ async def async_step_user(
elif not 1 <= inverter_count <= 32:
errors[ConfName.DEVICE_LIST] = "invalid_inverter_count"
else:
await self.async_set_unique_id(user_input[CONF_HOST])
new_unique_id = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
await self.async_set_unique_id(new_unique_id)

self._abort_if_unique_id_configured()

Expand Down Expand Up @@ -143,10 +144,19 @@ async def async_step_reconfigure(
user_input[ConfName.DEVICE_LIST] = device_list_from_string(
user_input[ConfName.DEVICE_LIST]
)
this_unique_id = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"

if this_unique_id != config_entry.unique_id:
self._async_abort_entries_match(
{
"host": user_input[CONF_HOST],
"port": user_input[CONF_PORT],
}
)

return self.async_update_reload_and_abort(
config_entry,
unique_id=config_entry.unique_id,
unique_id=this_unique_id,
data={**config_entry.data, **user_input},
reason="reconfigure_successful",
)
Expand Down Expand Up @@ -174,10 +184,6 @@ async def async_step_reconfigure(
class SolaredgeModbusMultiOptionsFlowHandler(OptionsFlow):
"""Handle an options flow for SolarEdge Modbus Multi."""

def __init__(self, config_entry: ConfigEntry):
"""Initialize options flow."""
self.config_entry = config_entry

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/solaredge_modbus_multi/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

REDACT_CONFIG = {"unique_id", "host"}
REDACT_INVERTER = {"identifiers", "C_SerialNumber", "serial_number"}
REDACT_METER = {"identifiers", "C_SerialNumber", "serial_number"}
REDACT_BATTERY = {"identifiers", "B_SerialNumber", "serial_number"}
REDACT_METER = {"identifiers", "C_SerialNumber", "serial_number", "via_device"}
REDACT_BATTERY = {"identifiers", "B_SerialNumber", "serial_number", "via_device"}


def format_values(format_input) -> Any:
Expand Down
8 changes: 6 additions & 2 deletions custom_components/solaredge_modbus_multi/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,19 @@ async def _async_init_solaredge(self) -> None:
_LOGGER.warning(
(
"Power Control Options: Storage Control is enabled. "
"Use at your own risk!"
"Use at your own risk! "
"Adjustable parameters in Modbus registers are intended for "
"long-term storage. Periodic changes may damage the flash memory."
),
)

if self.option_site_limit_control:
_LOGGER.warning(
(
"Power Control Options: Site Limit Control is enabled. "
"Use at your own risk!"
"Use at your own risk! "
"Adjustable parameters in Modbus registers are intended for "
"long-term storage. Periodic changes may damage the flash memory."
),
)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/solaredge_modbus_multi/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,<3.8"],
"version": "3.0.4"
"version": "3.0.6"
}
26 changes: 21 additions & 5 deletions custom_components/solaredge_modbus_multi/repairs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from homeassistant.exceptions import HomeAssistantError

from .config_flow import generate_config_schema
from .const import ConfDefaultStr, ConfName
from .const import DOMAIN, ConfDefaultStr, ConfName
from .helpers import device_list_from_string, host_valid


Expand Down Expand Up @@ -64,12 +64,28 @@ async def async_step_confirm(
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}
this_unique_id = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
existing_entry = (
self.hass.config_entries.async_entry_for_domain_unique_id(
DOMAIN, this_unique_id
)
)

return self.async_create_entry(title="", data={})
if (
existing_entry is not None
and self._entry.unique_id != this_unique_id
):
errors[CONF_HOST] = "already_configured"
errors[CONF_PORT] = "already_configured"

else:
self.hass.config_entries.async_update_entry(
self._entry,
unique_id=this_unique_id,
data={**self._entry.data, **user_input},
)

return self.async_create_entry(title="", data={})

else:
reconfig_device_list = ",".join(
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "The ID list contains an empty or undefined value."
},
"abort": {
"already_configured": "Device is already configured",
"already_configured": "Host and port is already configured in another hub.",
"reconfigure_successful": "Re-configuration was successful"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Enable Storage Control",
"adv_site_limit_control": "Enable Site Limit Control"
},
"description": "Warning: These options can violate utility agreements, alter your utility billing, may require special equipment, and overwrite provisioning by SolarEdge or your installer. Use at your own risk!"
"description": "Warning: These options can violate utility agreements, alter your utility billing, may require special equipment, and overwrite provisioning by SolarEdge or your installer. Use at your own risk! Adjustable parameters in Modbus registers are intended for long-term storage. Periodic changes may damage the flash memory."
},
"battery_options": {
"title": "Battery Options",
Expand Down Expand Up @@ -93,7 +93,8 @@
"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."
"empty_device_id": "The ID list contains an empty or undefined value.",
"already_configured": "Host and port is already configured in another hub."
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert."
},
"abort": {
"already_configured": "Gerät ist bereits konfiguriert",
"already_configured": "Host und Port sind bereits in einem anderen Hub konfiguriert.",
"reconfigure_successful": "Die Neukonfiguration war erfolgreich"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Speichersteuerung aktivieren",
"adv_site_limit_control": "Site-Limit-Kontrolle aktivieren"
},
"description": "Warnung: Diese Optionen können gegen Stromverträge verstoßen, Ihre Stromabrechnung ändern, möglicherweise spezielle Geräte erfordern und die Bereitstellung durch SolarEdge oder Ihren Installateur überschreiben. Benutzung auf eigene Gefahr!"
"description": "Warnung: Diese Optionen können gegen Stromverträge verstoßen, Ihre Stromabrechnung ändern, möglicherweise spezielle Geräte erfordern und die Bereitstellung durch SolarEdge oder Ihren Installateur überschreiben. Benutzung auf eigene Gefahr! Einstellbare Parameter in Modbus-Registern sind für die Langzeitspeicherung vorgesehen. Regelmäßige Änderungen können den Flash-Speicher beschädigen."
},
"battery_options": {
"title": "Batterieoptionen",
Expand Down Expand Up @@ -94,7 +94,8 @@
"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."
"empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert.",
"already_configured": "Host und Port sind bereits in einem anderen Hub konfiguriert."
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "The ID list contains an empty or undefined value."
},
"abort": {
"already_configured": "Device is already configured",
"already_configured": "Host and port is already configured in another hub.",
"reconfigure_successful": "Re-configuration was successful"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Enable Storage Control",
"adv_site_limit_control": "Enable Site Limit Control"
},
"description": "Warning: These options can violate utility agreements, alter your utility billing, may require special equipment, and overwrite provisioning by SolarEdge or your installer. Use at your own risk!"
"description": "Warning: These options can violate utility agreements, alter your utility billing, may require special equipment, and overwrite provisioning by SolarEdge or your installer. Use at your own risk! Adjustable parameters in Modbus registers are intended for long-term storage. Periodic changes may damage the flash memory."
},
"battery_options": {
"title": "Battery Options",
Expand Down Expand Up @@ -93,7 +93,8 @@
"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."
"empty_device_id": "The ID list contains an empty or undefined value.",
"already_configured": "Host and port is already configured in another hub."
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "La liste d'ID contient une valeur vide ou non définie."
},
"abort": {
"already_configured": "L'appareil est déjà configuré",
"already_configured": "L'hôte et le port sont déjà configurés dans un autre hub.",
"reconfigure_successful": "La reconfiguration a réussi"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Activer le contrôle du stockage",
"adv_site_limit_control": "Activer le contrôle des limites du site"
},
"description": "Avertissement : Ces options peuvent enfreindre l'accord d'utilisation, modifier la facturation de vos services, nécessiter un équipement spécial et écraser le provisionnement par SolarEdge ou votre installateur. À utiliser à vos risques et périls!"
"description": "Avertissement : Ces options peuvent enfreindre l'accord d'utilisation, modifier la facturation de vos services, nécessiter un équipement spécial et écraser le provisionnement par SolarEdge ou votre installateur. À utiliser à vos risques et périls! Les paramètres réglables dans les registres Modbus sont destinés au stockage à long terme. Des modifications périodiques peuvent endommager la mémoire flash."
},
"battery_options": {
"title": "Options de batterie",
Expand Down Expand Up @@ -94,7 +94,8 @@
"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."
"empty_device_id": "La liste d'ID contient une valeur vide ou non définie.",
"already_configured": "L'hôte et le port sont déjà configurés dans un autre hub."
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "L'elenco ID contiene un valore vuoto o non definito."
},
"abort": {
"already_configured": "Il dispositivo è già configurato",
"already_configured": "L'host e la porta sono già configurati in un altro hub.",
"reconfigure_successful": "La riconfigurazione ha avuto successo"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Abilita il controllo dell'archiviazione",
"adv_site_limit_control": "Abilita il controllo dei limiti del sito"
},
"description": "Avvertenza: queste opzioni possono violare i contratti dei servizi pubblici, alterare la fatturazione dei servizi pubblici, potrebbero richiedere apparecchiature speciali e sovrascrivere la fornitura da parte di SolarEdge o dell'installatore. Utilizzare a proprio rischio!"
"description": "Avvertenza: queste opzioni possono violare i contratti dei servizi pubblici, alterare la fatturazione dei servizi pubblici, potrebbero richiedere apparecchiature speciali e sovrascrivere la fornitura da parte di SolarEdge o dell'installatore. Utilizzare a proprio rischio! I parametri regolabili nei registri Modbus sono destinati alla memorizzazione a lungo termine. Modifiche periodiche potrebbero danneggiare la memoria flash."
},
"battery_options": {
"title": "Opzioni batteria",
Expand Down Expand Up @@ -94,7 +94,8 @@
"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."
"empty_device_id": "L'elenco ID contiene un valore vuoto o non definito.",
"already_configured": "L'host e la porta sono già configurati in un altro hub."
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions custom_components/solaredge_modbus_multi/translations/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"empty_device_id": "ID-listen inneholder en tom eller udefinert verdi."
},
"abort": {
"already_configured": "Enheten er allerede konfigurert",
"already_configured": "Vert og port er allerede konfigurert i en annen hub.",
"reconfigure_successful": "Omkonfigureringen var vellykket"
}
},
Expand All @@ -54,7 +54,7 @@
"adv_storage_control": "Aktiver lagringskontroll",
"adv_site_limit_control": "Aktiver Site Limit Control"
},
"description": "Advarsel: Disse alternativene kan bryte forsyningsavtaler, endre forbruksfaktureringen, kan kreve spesialutstyr og overskrive klargjøring av SolarEdge eller installatøren. Bruk på eget ansvar!"
"description": "Advarsel: Disse alternativene kan bryte forsyningsavtaler, endre forbruksfaktureringen, kan kreve spesialutstyr og overskrive klargjøring av SolarEdge eller installatøren. Bruk på eget ansvar! Justerbare parametere i Modbus-registre er beregnet for langtidslagring. Periodiske endringer kan skade flashminnet."
},
"battery_options": {
"title": "Batterialternativer",
Expand Down Expand Up @@ -94,7 +94,8 @@
"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."
"empty_device_id": "ID-listen inneholder en tom eller udefinert verdi.",
"already_configured": "Vert og port er allerede konfigurert i en annen hub."
}
}
}
Expand Down
Loading

0 comments on commit 3153977

Please sign in to comment.