Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion custom_components/vimar_intercom/options_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
# PICG dichiarato dal citofono stesso (get_info.php?action=nickname).
# Resta None quando la rubrica arriva da un file caricato a mano.
self._picg_from_rest: str | None = None
self._internal_panel_suggestion = ""
self._phonebook_source = "rubrica.db"

async def async_step_init(
Expand All @@ -342,10 +343,62 @@ async def async_step_init(
"""Menu: impostazioni a mano, rubrica dal citofono, o file rubrica.db."""
return self.async_show_menu(
step_id="init",
menu_options=["settings", "homekit", "av_key", "fetch_rubrica", "fetch_rubrica_cloud",
menu_options=["settings", "internal_panel", "homekit", "av_key", "fetch_rubrica", "fetch_rubrica_cloud",
"import_rubrica"],
)

async def async_step_internal_panel(self, user_input: dict | None = None) -> FlowResult:
"""Propose the declared main indoor monitor; save only after confirmation."""
current = {**self._entry.data, **self._entry.options}
errors: dict[str, str] = {}
if user_input is not None:
target = str(user_input.get(KEY_INTERNAL_PANEL_TARGET) or "").strip()
if validate.sip_target(target):
return self.async_create_entry(
title="", data={**self._entry.options, KEY_INTERNAL_PANEL_TARGET: target})
errors[KEY_INTERNAL_PANEL_TARGET] = "invalid_target"
else:
hub = (self.hass.data.get(DOMAIN, {}).get(self._entry.entry_id) or {}).get("hub")
nicks = (hub.stats.get("nicknames") or []) if hub else []
picg = str(current.get(KEY_PICG_TARGET) or PICG_TARGET).strip()
has_picg = any(str(n.get("role") or "").upper() == rest_client.ROLE_PICG
for n in nicks)
if not has_picg:
if not hub or not hub.registered:
errors["base"] = "internal_panel_unavailable"
elif validate.sip_target(picg):
result = await hub.async_find_picg([picg], sip_timeout=20, reply_wait=10)
nicks = result.get("nicknames") or []
if not result.get("ok"):
errors["base"] = "internal_panel_unavailable"
elif not nicks and not result.get("reply_after") and not any(
p.get("outcome") == "replied" for p in result.get("probes", [])
):
errors["base"] = "internal_panel_no_reply"
candidates = {str(n.get("ext") or "").strip() for n in nicks
if str(n.get("role") or "").upper() == rest_client.ROLE_PICG
and validate.sip_target(str(n.get("ext") or "").strip())}
self._internal_panel_suggestion = next(iter(candidates)) if len(candidates) == 1 else ""
if not self._internal_panel_suggestion and not errors:
errors["base"] = "internal_panel_not_found"
suggestion = self._internal_panel_suggestion
if suggestion == str(current.get(KEY_SGA_TARGET) or SGA_TARGET).strip():
suggestion = ""
return self.async_show_form(
step_id="internal_panel",
data_schema=vol.Schema({vol.Required(
KEY_INTERNAL_PANEL_TARGET,
default=(user_input or {}).get(KEY_INTERNAL_PANEL_TARGET,
suggestion or current.get(KEY_INTERNAL_PANEL_TARGET)
or INTERNAL_PANEL_TARGET),
): str}),
errors=errors,
description_placeholders={
"detected": self._internal_panel_suggestion or "—",
"current": str(current.get(KEY_INTERNAL_PANEL_TARGET) or INTERNAL_PANEL_TARGET),
},
)

async def async_step_settings(
self, user_input: dict | None = None
) -> FlowResult:
Expand Down
11 changes: 11 additions & 0 deletions custom_components/vimar_intercom/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"init": {
"title": "Impostazioni Vimar Intercom",
"menu_options": {
"internal_panel": "Rileva il posto interno",
"settings": "Impostazioni di rete e attuatori",
"homekit": "HomeKit",
"av_key": "Chiave dello stream /av",
Expand All @@ -87,6 +88,13 @@
"fetch_rubrica_cloud": "Scarica la rubrica dal cloud Vimar"
}
},
"internal_panel": {
"title": "Rileva il posto interno",
"description": "L’impianto dichiara il PICG {detected}. La destinazione attuale di Chiama Casa è {current}. Se il PICG dichiarato è diverso dall’SGA viene proposto come posto interno; altrimenti resta la destinazione attuale, perché il PICG può essere un controllore anziché un monitor. Conferma la destinazione o inserisci l’indirizzo noto di un posto interno. Il salvataggio non avvia una chiamata.",
"data": {
"internal_panel_target": "Indirizzo SIP del posto interno"
}
},
"settings": {
"title": "Impostazioni Vimar Intercom",
"description": "Rete SIP e attuatori dinamici. Nel campo Attuatori incolla la lista JSON prodotta da tools/parse_rubrica.py, oppure torna al menu e usa \"Importa attuatori da rubrica.db\". {actuators_error}",
Expand Down Expand Up @@ -207,6 +215,9 @@
"invalid_actuator_target": "Target attuatore non valido ({actuators_error}): usa solo cifre (es. 55001) oppure AUTO.",
"rubrica_import_failed": "Importazione fallita. Vedi il dettaglio nella descrizione.",
"rubrica_no_actuators": "Nessun attuatore trovato per il GID specificato. Vedi la descrizione.",
"internal_panel_not_found": "La risposta dei nickname non dichiara un PICG valido e univoco. Inserisci manualmente l’indirizzo noto di un posto interno.",
"internal_panel_no_reply": "Non è arrivata una risposta dei nickname dal PICG configurato. Alcuni impianti cloud non rispondono a GET_NICKS anche a un indirizzo esistente. Questo non dimostra che l’indirizzo sia errato; inserisci manualmente l’indirizzo noto di un posto interno.",
"internal_panel_unavailable": "La ricerca dei nickname non è disponibile: l’integrazione potrebbe essere disconnessa o un’altra ricerca potrebbe essere in corso. Riprova quando disponibile o inserisci manualmente l’indirizzo noto di un posto interno.",
"invalid_target": "Valore non valido: usa solo cifre (es. 55001).",
"invalid_url": "URL non valido: deve iniziare con http:// o https:// e avere un host.",
"no_local_proxy": "Manca l'indirizzo del citofono: impostalo in «Impostazioni di rete e attuatori».",
Expand Down
11 changes: 11 additions & 0 deletions custom_components/vimar_intercom/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"init": {
"title": "Vimar Intercom settings",
"menu_options": {
"internal_panel": "Find indoor monitor",
"settings": "Network and actuator settings",
"homekit": "HomeKit",
"av_key": "/av stream key",
Expand All @@ -87,6 +88,13 @@
"fetch_rubrica_cloud": "Download the phonebook from the Vimar cloud"
}
},
"internal_panel": {
"title": "Find indoor monitor",
"description": "The system declares PICG {detected}. The current Call Home destination is {current}. If the declared PICG differs from the SGA, it is proposed as the indoor monitor; otherwise the current destination is kept, because the PICG may be a controller rather than a monitor. Confirm the destination or enter a known indoor monitor address. Saving does not place a call.",
"data": {
"internal_panel_target": "Indoor monitor SIP address"
}
},
"settings": {
"title": "Vimar Intercom settings",
"description": "SIP network and dynamic actuators. In the Actuators field paste the JSON list produced by tools/parse_rubrica.py, or go back to the menu and use \"Import actuators from rubrica.db\". {actuators_error}",
Expand Down Expand Up @@ -207,6 +215,9 @@
"invalid_actuator_target": "Invalid actuator target ({actuators_error}): digits only (e.g. 55001) or AUTO.",
"rubrica_import_failed": "Import failed. See description above for details.",
"rubrica_no_actuators": "No actuators found for the specified GID. See description above.",
"internal_panel_not_found": "The nickname reply does not declare a unique valid PICG. Enter a known indoor monitor address manually.",
"internal_panel_no_reply": "No nickname reply arrived from the configured PICG. Some cloud plants do not answer GET_NICKS even at an existing address. This does not prove the address is wrong; enter a known indoor monitor address manually.",
"internal_panel_unavailable": "The nickname lookup could not run: the integration may be disconnected or another search may be in progress. Retry once it is available, or enter a known indoor monitor address manually.",
"invalid_target": "Invalid value: digits only (e.g. 55001).",
"invalid_url": "Invalid URL: it must start with http:// or https:// and have a host.",
"no_local_proxy": "The intercom address is missing: set it under \"Network and actuator settings\".",
Expand Down
11 changes: 11 additions & 0 deletions custom_components/vimar_intercom/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"init": {
"title": "Impostazioni Vimar Intercom",
"menu_options": {
"internal_panel": "Rileva il posto interno",
"settings": "Impostazioni di rete e attuatori",
"homekit": "HomeKit",
"av_key": "Chiave dello stream /av",
Expand All @@ -87,6 +88,13 @@
"fetch_rubrica_cloud": "Scarica la rubrica dal cloud Vimar"
}
},
"internal_panel": {
"title": "Rileva il posto interno",
"description": "L’impianto dichiara il PICG {detected}. La destinazione attuale di Chiama Casa è {current}. Se il PICG dichiarato è diverso dall’SGA viene proposto come posto interno; altrimenti resta la destinazione attuale, perché il PICG può essere un controllore anziché un monitor. Conferma la destinazione o inserisci l’indirizzo noto di un posto interno. Il salvataggio non avvia una chiamata.",
"data": {
"internal_panel_target": "Indirizzo SIP del posto interno"
}
},
"settings": {
"title": "Impostazioni Vimar Intercom",
"description": "Rete SIP e attuatori dinamici. Nel campo Attuatori incolla la lista JSON prodotta da tools/parse_rubrica.py, oppure torna al menu e usa \"Importa attuatori da rubrica.db\". {actuators_error}",
Expand Down Expand Up @@ -207,6 +215,9 @@
"invalid_actuator_target": "Target attuatore non valido ({actuators_error}): usa solo cifre (es. 55001) oppure AUTO.",
"rubrica_import_failed": "Importazione fallita. Vedi il dettaglio nella descrizione.",
"rubrica_no_actuators": "Nessun attuatore trovato per il GID specificato. Vedi la descrizione.",
"internal_panel_not_found": "La risposta dei nickname non dichiara un PICG valido e univoco. Inserisci manualmente l’indirizzo noto di un posto interno.",
"internal_panel_no_reply": "Non è arrivata una risposta dei nickname dal PICG configurato. Alcuni impianti cloud non rispondono a GET_NICKS anche a un indirizzo esistente. Questo non dimostra che l’indirizzo sia errato; inserisci manualmente l’indirizzo noto di un posto interno.",
"internal_panel_unavailable": "La ricerca dei nickname non è disponibile: l’integrazione potrebbe essere disconnessa o un’altra ricerca potrebbe essere in corso. Riprova quando disponibile o inserisci manualmente l’indirizzo noto di un posto interno.",
"invalid_target": "Valore non valido: usa solo cifre (es. 55001).",
"invalid_url": "URL non valido: deve iniziare con http:// o https:// e avere un host.",
"no_local_proxy": "Manca l'indirizzo del citofono: impostalo in «Impostazioni di rete e attuatori».",
Expand Down
4 changes: 4 additions & 0 deletions docs/CONFIGURATION.it.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ Impostazioni → Vimar Intercom → **Configura**:

L'immagine della camera fra una chiamata e l'altra (l'ultima foto dello squillo) è visibile a ogni utente di Home Assistant che vede l'entità camera; `allowed_users` limita la cronologia degli squilli e i media dal vivo, non l'entità camera.

### Rilevare il posto interno

Configura → **Rileva il posto interno** propone il posto interno capogruppo dichiarato nella risposta `GET_NICKS` (ruolo `PICG`). Usa i nickname già ricevuti oppure li richiede al PICG configurato, senza cercare altri indirizzi. Mostra la destinazione attuale di **Chiama Casa** e salva quella proposta solo dopo conferma. Non modifica SGA, PICG, targa video o attuatori e non avvia chiamate. Se non trova un PICG univoco, non indovina la destinazione; resta possibile inserire un indirizzo noto a mano. Verificato su un Tab 7S Up 40517, SW 2.1.0203, in cloud; la possibilità di chiamare il capogruppo va verificata sugli altri impianti. Un PICG uguale all’SGA effettivo non viene proposto: si mantiene la destinazione attuale di Chiama Casa.

### Segreteria

C'è un solo switch *Segreteria* (Configurazione, pagina del dispositivo). Acceso, usa il
Expand Down
4 changes: 4 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ Settings → Vimar Intercom → **Configure**:

The camera image between calls (the last ring photo) is visible to every Home Assistant user who can see the camera entity; `allowed_users` limits the ring history and live media, not the camera entity.

### Finding the indoor monitor

Configure → **Find indoor monitor** proposes the main indoor monitor declared in a `GET_NICKS` reply (role `PICG`). It uses previously received nicknames or requests them from the configured PICG, without scanning other addresses. It shows the current **Call Home** destination and saves the proposal only when confirmed. SGA, PICG, camera and actuator settings are preserved, and no call is placed. Without a unique declared PICG it does not guess a destination; a known address can still be entered manually. The mapping was verified on a Tab 7S Up 40517, SW 2.1.0203, over the cloud; whether the main monitor accepts calls needs checking on other plants. A PICG equal to the effective SGA is not proposed: the current Call Home destination is kept.

### Voicemail

There is one *Voicemail* switch (Configuration, device page). Turned on, it uses Home
Expand Down
Loading
Loading