Skip to content

Commit 3153977

Browse files
Merge branch 'main' into modbus-string-helper
2 parents 873e012 + 5f3bfcd commit 3153977

File tree

16 files changed

+105
-46
lines changed

16 files changed

+105
-46
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ After rebooting Home Assistant, this integration can be configured through the i
3838
[WillCodeForCats/solaredge-modbus-multi/wiki](https://github.com/WillCodeForCats/solaredge-modbus-multi/wiki)
3939

4040
### Required Versions
41-
* Home Assistant 2024.9.0 or newer
41+
* Home Assistant 2024.12.0 or newer
4242
* Python 3.11 or newer
4343
* pymodbus 3.6.6 through 3.7.4
4444

custom_components/solaredge_modbus_multi/__init__.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import voluptuous as vol
1010
from homeassistant.config_entries import ConfigEntry
11-
from homeassistant.const import CONF_SCAN_INTERVAL, Platform
11+
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SCAN_INTERVAL, Platform
1212
from homeassistant.core import HomeAssistant
1313
from homeassistant.helpers.device_registry import DeviceEntry
1414
from homeassistant.helpers.typing import ConfigType
@@ -161,10 +161,11 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
161161
f"{config_entry.version}.{config_entry.minor_version}"
162162
)
163163

164-
if config_entry.version > 1:
164+
if config_entry.version > 2:
165165
return False
166166

167167
if config_entry.version == 1:
168+
_LOGGER.debug("Migrating from version 1")
168169

169170
update_data = {**config_entry.data}
170171
update_options = {**config_entry.options}
@@ -196,6 +197,30 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
196197
minor_version=0,
197198
)
198199

200+
if config_entry.version == 2 and config_entry.minor_version < 1:
201+
_LOGGER.debug("Migrating from version 2.0")
202+
203+
config_entry_data = {**config_entry.data}
204+
205+
# Use host:port address string as the config entry unique ID.
206+
# This is technically not a valid HA unique ID, but with modbus
207+
# we can't know anything like a serial number per IP since a
208+
# single SE modbus IP could have up to 32 different serial numbers
209+
# and the "leader" modbus unit id can't be known programmatically.
210+
211+
old_unique_id = config_entry.unique_id
212+
new_unique_id = f"{config_entry_data[CONF_HOST]}:{config_entry_data[CONF_PORT]}"
213+
214+
_LOGGER.warning(
215+
"Migrating config entry unique ID from %s to %s",
216+
old_unique_id,
217+
new_unique_id,
218+
)
219+
220+
hass.config_entries.async_update_entry(
221+
config_entry, unique_id=new_unique_id, version=2, minor_version=1
222+
)
223+
199224
_LOGGER.warning(
200225
"Migrated to config version "
201226
f"{config_entry.version}.{config_entry.minor_version}"

custom_components/solaredge_modbus_multi/config_flow.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ class SolaredgeModbusMultiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
4949
"""Handle a config flow for SolarEdge Modbus Multi."""
5050

5151
VERSION = 2
52-
MINOR_VERSION = 0
52+
MINOR_VERSION = 1
5353

5454
@staticmethod
5555
@callback
5656
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
5757
"""Create the options flow for SolarEdge Modbus Multi."""
58-
return SolaredgeModbusMultiOptionsFlowHandler(config_entry)
58+
return SolaredgeModbusMultiOptionsFlowHandler()
5959

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

8990
self._abort_if_unique_id_configured()
9091

@@ -143,10 +144,19 @@ async def async_step_reconfigure(
143144
user_input[ConfName.DEVICE_LIST] = device_list_from_string(
144145
user_input[ConfName.DEVICE_LIST]
145146
)
147+
this_unique_id = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
148+
149+
if this_unique_id != config_entry.unique_id:
150+
self._async_abort_entries_match(
151+
{
152+
"host": user_input[CONF_HOST],
153+
"port": user_input[CONF_PORT],
154+
}
155+
)
146156

147157
return self.async_update_reload_and_abort(
148158
config_entry,
149-
unique_id=config_entry.unique_id,
159+
unique_id=this_unique_id,
150160
data={**config_entry.data, **user_input},
151161
reason="reconfigure_successful",
152162
)
@@ -174,10 +184,6 @@ async def async_step_reconfigure(
174184
class SolaredgeModbusMultiOptionsFlowHandler(OptionsFlow):
175185
"""Handle an options flow for SolarEdge Modbus Multi."""
176186

177-
def __init__(self, config_entry: ConfigEntry):
178-
"""Initialize options flow."""
179-
self.config_entry = config_entry
180-
181187
async def async_step_init(
182188
self, user_input: dict[str, Any] | None = None
183189
) -> FlowResult:

custom_components/solaredge_modbus_multi/diagnostics.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
REDACT_CONFIG = {"unique_id", "host"}
1515
REDACT_INVERTER = {"identifiers", "C_SerialNumber", "serial_number"}
16-
REDACT_METER = {"identifiers", "C_SerialNumber", "serial_number"}
17-
REDACT_BATTERY = {"identifiers", "B_SerialNumber", "serial_number"}
16+
REDACT_METER = {"identifiers", "C_SerialNumber", "serial_number", "via_device"}
17+
REDACT_BATTERY = {"identifiers", "B_SerialNumber", "serial_number", "via_device"}
1818

1919

2020
def format_values(format_input) -> Any:

custom_components/solaredge_modbus_multi/hub.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,15 +220,19 @@ async def _async_init_solaredge(self) -> None:
220220
_LOGGER.warning(
221221
(
222222
"Power Control Options: Storage Control is enabled. "
223-
"Use at your own risk!"
223+
"Use at your own risk! "
224+
"Adjustable parameters in Modbus registers are intended for "
225+
"long-term storage. Periodic changes may damage the flash memory."
224226
),
225227
)
226228

227229
if self.option_site_limit_control:
228230
_LOGGER.warning(
229231
(
230232
"Power Control Options: Site Limit Control is enabled. "
231-
"Use at your own risk!"
233+
"Use at your own risk! "
234+
"Adjustable parameters in Modbus registers are intended for "
235+
"long-term storage. Periodic changes may damage the flash memory."
232236
),
233237
)
234238

custom_components/solaredge_modbus_multi/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"issue_tracker": "https://github.com/WillCodeForCats/solaredge-modbus-multi/issues",
1111
"loggers": ["custom_components.solaredge_modbus_multi"],
1212
"requirements": ["pymodbus>=3.6.6,<3.8"],
13-
"version": "3.0.4"
13+
"version": "3.0.6"
1414
}

custom_components/solaredge_modbus_multi/repairs.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from homeassistant.exceptions import HomeAssistantError
1414

1515
from .config_flow import generate_config_schema
16-
from .const import ConfDefaultStr, ConfName
16+
from .const import DOMAIN, ConfDefaultStr, ConfName
1717
from .helpers import device_list_from_string, host_valid
1818

1919

@@ -64,12 +64,28 @@ async def async_step_confirm(
6464
user_input[ConfName.DEVICE_LIST] = device_list_from_string(
6565
user_input[ConfName.DEVICE_LIST]
6666
)
67-
68-
self.hass.config_entries.async_update_entry(
69-
self._entry, data={**self._entry.data, **user_input}
67+
this_unique_id = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
68+
existing_entry = (
69+
self.hass.config_entries.async_entry_for_domain_unique_id(
70+
DOMAIN, this_unique_id
71+
)
7072
)
7173

72-
return self.async_create_entry(title="", data={})
74+
if (
75+
existing_entry is not None
76+
and self._entry.unique_id != this_unique_id
77+
):
78+
errors[CONF_HOST] = "already_configured"
79+
errors[CONF_PORT] = "already_configured"
80+
81+
else:
82+
self.hass.config_entries.async_update_entry(
83+
self._entry,
84+
unique_id=this_unique_id,
85+
data={**self._entry.data, **user_input},
86+
)
87+
88+
return self.async_create_entry(title="", data={})
7389

7490
else:
7591
reconfig_device_list = ",".join(

custom_components/solaredge_modbus_multi/strings.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "The ID list contains an empty or undefined value."
3131
},
3232
"abort": {
33-
"already_configured": "Device is already configured",
33+
"already_configured": "Host and port is already configured in another hub.",
3434
"reconfigure_successful": "Re-configuration was successful"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Enable Storage Control",
5555
"adv_site_limit_control": "Enable Site Limit Control"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Battery Options",
@@ -93,7 +93,8 @@
9393
"invalid_tcp_port": "Valid port range is 1 to 65535.",
9494
"invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.",
9595
"invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.",
96-
"empty_device_id": "The ID list contains an empty or undefined value."
96+
"empty_device_id": "The ID list contains an empty or undefined value.",
97+
"already_configured": "Host and port is already configured in another hub."
9798
}
9899
}
99100
}

custom_components/solaredge_modbus_multi/translations/de.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert."
3131
},
3232
"abort": {
33-
"already_configured": "Gerät ist bereits konfiguriert",
33+
"already_configured": "Host und Port sind bereits in einem anderen Hub konfiguriert.",
3434
"reconfigure_successful": "Die Neukonfiguration war erfolgreich"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Speichersteuerung aktivieren",
5555
"adv_site_limit_control": "Site-Limit-Kontrolle aktivieren"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Batterieoptionen",
@@ -94,7 +94,8 @@
9494
"invalid_tcp_port": "Der gültige Portbereich ist 1 bis 65535.",
9595
"invalid_range_format": "Der Eintrag sieht aus wie ein Bereich, es ist jedoch nur ein „-“ pro Bereich zulässig.",
9696
"invalid_range_lte": "Die Start-ID in einem Bereich muss kleiner oder gleich der End-ID sein.",
97-
"empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert."
97+
"empty_device_id": "Die ID-Liste enthält einen leeren oder undefinierten Wert.",
98+
"already_configured": "Host und Port sind bereits in einem anderen Hub konfiguriert."
9899
}
99100
}
100101
}

custom_components/solaredge_modbus_multi/translations/en.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "The ID list contains an empty or undefined value."
3131
},
3232
"abort": {
33-
"already_configured": "Device is already configured",
33+
"already_configured": "Host and port is already configured in another hub.",
3434
"reconfigure_successful": "Re-configuration was successful"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Enable Storage Control",
5555
"adv_site_limit_control": "Enable Site Limit Control"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Battery Options",
@@ -93,7 +93,8 @@
9393
"invalid_tcp_port": "Valid port range is 1 to 65535.",
9494
"invalid_range_format": "Entry looks like a range but only one '-' per range is allowed.",
9595
"invalid_range_lte": "Starting ID in a range must be less than or equal to the end ID.",
96-
"empty_device_id": "The ID list contains an empty or undefined value."
96+
"empty_device_id": "The ID list contains an empty or undefined value.",
97+
"already_configured": "Host and port is already configured in another hub."
9798
}
9899
}
99100
}

custom_components/solaredge_modbus_multi/translations/fr.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "La liste d'ID contient une valeur vide ou non définie."
3131
},
3232
"abort": {
33-
"already_configured": "L'appareil est déjà configuré",
33+
"already_configured": "L'hôte et le port sont déjà configurés dans un autre hub.",
3434
"reconfigure_successful": "La reconfiguration a réussi"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Activer le contrôle du stockage",
5555
"adv_site_limit_control": "Activer le contrôle des limites du site"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Options de batterie",
@@ -94,7 +94,8 @@
9494
"invalid_tcp_port": "La plage de ports valide est comprise entre 1 et 65535.",
9595
"invalid_range_format": "L'entrée ressemble à une plage mais un seul « - » par plage est autorisé.",
9696
"invalid_range_lte": "L’ID de début d’une plage doit être inférieur ou égal à l’ID de fin.",
97-
"empty_device_id": "La liste d'ID contient une valeur vide ou non définie."
97+
"empty_device_id": "La liste d'ID contient une valeur vide ou non définie.",
98+
"already_configured": "L'hôte et le port sont déjà configurés dans un autre hub."
9899
}
99100
}
100101
}

custom_components/solaredge_modbus_multi/translations/it.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "L'elenco ID contiene un valore vuoto o non definito."
3131
},
3232
"abort": {
33-
"already_configured": "Il dispositivo è già configurato",
33+
"already_configured": "L'host e la porta sono già configurati in un altro hub.",
3434
"reconfigure_successful": "La riconfigurazione ha avuto successo"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Abilita il controllo dell'archiviazione",
5555
"adv_site_limit_control": "Abilita il controllo dei limiti del sito"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Opzioni batteria",
@@ -94,7 +94,8 @@
9494
"invalid_tcp_port": "L'intervallo di porte valido è compreso tra 1 e 65535.",
9595
"invalid_range_format": "L'immissione sembra un intervallo ma è consentito solo un '-' per intervallo.",
9696
"invalid_range_lte": "L'ID iniziale in un intervallo deve essere inferiore o uguale all'ID finale.",
97-
"empty_device_id": "L'elenco ID contiene un valore vuoto o non definito."
97+
"empty_device_id": "L'elenco ID contiene un valore vuoto o non definito.",
98+
"already_configured": "L'host e la porta sono già configurati in un altro hub."
9899
}
99100
}
100101
}

custom_components/solaredge_modbus_multi/translations/nb.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"empty_device_id": "ID-listen inneholder en tom eller udefinert verdi."
3131
},
3232
"abort": {
33-
"already_configured": "Enheten er allerede konfigurert",
33+
"already_configured": "Vert og port er allerede konfigurert i en annen hub.",
3434
"reconfigure_successful": "Omkonfigureringen var vellykket"
3535
}
3636
},
@@ -54,7 +54,7 @@
5454
"adv_storage_control": "Aktiver lagringskontroll",
5555
"adv_site_limit_control": "Aktiver Site Limit Control"
5656
},
57-
"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!"
57+
"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."
5858
},
5959
"battery_options": {
6060
"title": "Batterialternativer",
@@ -94,7 +94,8 @@
9494
"invalid_tcp_port": "Gyldig portområde er 1 til 65535.",
9595
"invalid_range_format": "Oppføring ser ut som et område, men bare én '-' per område er tillatt.",
9696
"invalid_range_lte": "Start-ID i et område må være mindre enn eller lik slutt-ID.",
97-
"empty_device_id": "ID-listen inneholder en tom eller udefinert verdi."
97+
"empty_device_id": "ID-listen inneholder en tom eller udefinert verdi.",
98+
"already_configured": "Vert og port er allerede konfigurert i en annen hub."
9899
}
99100
}
100101
}

0 commit comments

Comments
 (0)