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
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ All notable changes to HA Daily Counter will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.9] - 2025-12-11

### ✨ New Feature: Counter Reconfiguration via Options Flow

This release adds the ability to edit and reconfigure existing counters directly through the Home Assistant UI, without having to delete and recreate them.

### Added
- ✨ **Edit Counter Option**: New "Edit counter" action in the options flow menu
- 🔄 **Reconfigure Trigger Entity**: Ability to change the entity that triggers the counter
- 🔄 **Reconfigure Trigger State**: Ability to change the state that increments the counter
- 🔄 **Automatic Reload**: Integration automatically reloads when configuration changes are saved
- 📋 **Current Values Display**: Shows current configuration before making changes in the edit flow

### Changed
- Updated `__init__.py` to register an update listener that reloads the integration when options are modified
- Enhanced `options_flow.py` with new edit steps: `async_step_select_edit`, `async_step_edit_trigger_entity`, and `async_step_edit_trigger_state`
- Updated all translation files (en.json, es.json, strings.json) with new edit-related strings
- Updated version to 1.3.9 in manifest.json

### Technical Details
- Added `async_reload_entry` function in `__init__.py` to handle config entry reloads
- Registered update listener in `async_setup_entry` to detect option changes and trigger reload
- Modified `HADailyCounterOptionsFlow` class to track editing state with `_selected_edit_index` and `_editing_counter`
- Edit flow preserves counter ID to maintain entity continuity

### How to Use
1. Go to Settings → Devices & Services
2. Find your HA Daily Counter integration
3. Click "Configure" on any existing counter entry
4. Select "Edit counter" from the action menu
5. Choose which counter you want to edit
6. Update the trigger entity or trigger state
7. The integration will automatically reload with the new configuration

## [1.3.8] - 2025-12-10

### 🔧 Critical Bug Fix Release
Expand Down
137 changes: 137 additions & 0 deletions RELEASE_NOTES_v1.3.9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Release Notes for v1.3.9 / Notas de Lanzamiento v1.3.9

---

## 🇬🇧 English Version

### ✨ New Feature: Counter Reconfiguration via Options Flow

This release adds the ability to edit and reconfigure existing counters directly through the Home Assistant UI, without having to delete and recreate them.

#### What's new?
- ✨ **Edit Counter Option**: New "Edit counter" action in the options flow menu
- 🔄 **Reconfigure Trigger Entity**: Change the entity that triggers the counter
- 🔄 **Reconfigure Trigger State**: Change the state that increments the counter
- 🔄 **Automatic Reload**: Integration automatically reloads when configuration changes are saved
- 📋 **Current Values Display**: See current configuration before making changes

#### Who should use this?
**All users who want to modify their existing counters** without losing their current count values or having to delete and recreate the counter.

#### How to use the new feature?
1. Go to Settings → Devices & Services
2. Find your HA Daily Counter integration
3. Click "Configure" on any existing counter entry
4. Select "Edit counter" from the action menu
5. Choose which counter you want to edit
6. Update the trigger entity or trigger state
7. The integration will automatically reload with the new configuration

#### Technical Changes
- Added `async_reload_entry` function in `__init__.py` to handle config entry reloads
- Registered update listener in `async_setup_entry` to detect option changes
- Added `async_step_select_edit`, `async_step_edit_trigger_entity`, and `async_step_edit_trigger_state` methods to `HADailyCounterOptionsFlow`
- Updated translation files (en.json, es.json, strings.json) with new edit-related strings
- Updated version to 1.3.9 in manifest.json

#### Installation
1. Update via HACS or manually install v1.3.9
2. Restart Home Assistant
3. Navigate to your integration settings to try the new edit feature

#### Need help?
If you experience any issues:
1. Check your Home Assistant logs for errors
2. Try reloading the integration from Settings → Devices & Services
3. Report issues at: https://github.com/Geek-MD/HA_Daily_Counter/issues

---

## 🇪🇸 Versión en Español

### ✨ Nueva Funcionalidad: Reconfiguración de Contadores vía Options Flow

Este lanzamiento añade la capacidad de editar y reconfigurar contadores existentes directamente a través de la interfaz de Home Assistant, sin necesidad de eliminar y recrear.

#### ¿Qué hay de nuevo?
- ✨ **Opción de Editar Contador**: Nueva acción "Editar contador" en el menú de flujo de opciones
- 🔄 **Reconfigurar Entidad Disparadora**: Cambia la entidad que dispara el contador
- 🔄 **Reconfigurar Estado Disparador**: Cambia el estado que incrementa el contador
- 🔄 **Recarga Automática**: La integración se recarga automáticamente cuando se guardan los cambios de configuración
- 📋 **Visualización de Valores Actuales**: Ve la configuración actual antes de hacer cambios

#### ¿Quién debería usar esto?
**Todos los usuarios que quieran modificar sus contadores existentes** sin perder los valores actuales del contador o tener que eliminar y recrear el contador.

#### ¿Cómo usar la nueva funcionalidad?
1. Ve a Configuración → Dispositivos y Servicios
2. Encuentra tu integración HA Daily Counter
3. Haz clic en "Configurar" en cualquier entrada de contador existente
4. Selecciona "Editar contador" del menú de acciones
5. Elige qué contador quieres editar
6. Actualiza la entidad disparadora o el estado disparador
7. La integración se recargará automáticamente con la nueva configuración

#### Cambios Técnicos
- Agregada función `async_reload_entry` en `__init__.py` para manejar recargas de entradas de configuración
- Registrado listener de actualización en `async_setup_entry` para detectar cambios de opciones
- Agregados métodos `async_step_select_edit`, `async_step_edit_trigger_entity` y `async_step_edit_trigger_state` a `HADailyCounterOptionsFlow`
- Actualizados archivos de traducción (en.json, es.json, strings.json) con nuevas cadenas relacionadas con edición
- Actualizada versión a 1.3.9 en manifest.json

#### Instalación
1. Actualiza a través de HACS o instala manualmente la v1.3.9
2. Reinicia Home Assistant
3. Navega a la configuración de tu integración para probar la nueva función de edición

#### ¿Necesitas ayuda?
Si experimentas algún problema:
1. Verifica los registros de Home Assistant para errores
2. Intenta recargar la integración desde Configuración → Dispositivos y Servicios
3. Reporta problemas en: https://github.com/Geek-MD/HA_Daily_Counter/issues

---

## 📋 Copy-Paste for GitHub Release / Para copiar en GitHub Release

### Short Version / Versión Corta

**✨ New Feature: Counter Reconfiguration via Options Flow**

This release adds the ability to edit existing counters through the Home Assistant UI without deleting and recreating them.

**What's New:**
- ✨ Edit counter option in options flow menu
- 🔄 Reconfigure trigger entity and state
- 🔄 Automatic reload when changes are saved
- 📋 Display current values before editing

**How to Use:**
1. Go to Settings → Devices & Services
2. Click "Configure" on any counter
3. Select "Edit counter"
4. Update trigger entity or state
5. Changes apply automatically after save

**Installation:** Update via HACS and restart Home Assistant.

---

**✨ Nueva Funcionalidad: Reconfiguración de Contadores vía Options Flow**

Este lanzamiento añade la capacidad de editar contadores existentes a través de la interfaz de Home Assistant sin eliminarlos y recrearlos.

**Qué Hay de Nuevo:**
- ✨ Opción de editar contador en el menú de flujo de opciones
- 🔄 Reconfigurar entidad y estado disparador
- 🔄 Recarga automática cuando se guardan los cambios
- 📋 Mostrar valores actuales antes de editar

**Cómo Usar:**
1. Ve a Configuración → Dispositivos y Servicios
2. Haz clic en "Configurar" en cualquier contador
3. Selecciona "Editar contador"
4. Actualiza entidad o estado disparador
5. Los cambios se aplican automáticamente después de guardar

**Instalación:** Actualiza vía HACS y reinicia Home Assistant.
8 changes: 8 additions & 0 deletions custom_components/ha_daily_counter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
cast(Any, hass.config_entries).async_forward_entry_setups(entry, ["sensor"])
)

# Register update listener to reload when options change
entry.async_on_unload(entry.add_update_listener(async_reload_entry))

async def handle_reset_counter(call: ServiceCall) -> None:
"""Handle the reset_counter service call."""
entity_id = call.data.get("entity_id")
Expand Down Expand Up @@ -94,3 +97,8 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# Llamada a la versión plural de unload si existe; usar cast para evitar chequeos estáticos.
unloaded = await cast(Any, hass.config_entries).async_forward_entry_unloads(entry, ["sensor"])
return all(unloaded)


async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload config entry when options are updated."""
await hass.config_entries.async_reload(entry.entry_id)
2 changes: 1 addition & 1 deletion custom_components/ha_daily_counter/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "local_push",
"issue_tracker": "https://github.com/Geek-MD/HA_Daily_Counter/issues",
"requirements": [],
"version": "1.3.8"
"version": "1.3.9"
}
93 changes: 82 additions & 11 deletions custom_components/ha_daily_counter/options_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ def __init__(self, config_entry: ConfigEntry) -> None:
self._counters = list(config_entry.options.get("counters", []))
self._new_counter: Dict[str, Any] = {}
self._selected_delete_name: Optional[str] = None
self._selected_edit_index: Optional[int] = None
self._editing_counter: Dict[str, Any] = {}

async def async_step_init(self, user_input: Optional[Dict[str, Any]] = None) -> config_entries.FlowResult:
"""Initial step: add or delete a counter."""
"""Initial step: add, edit, or delete a counter."""
if user_input is not None:
if user_input["action"] == "add":
return await self.async_step_user()
elif user_input["action"] == "edit":
return await self.async_step_select_edit()
elif user_input["action"] == "delete":
return await self.async_step_select_delete()

Expand All @@ -40,6 +44,7 @@ async def async_step_init(self, user_input: Optional[Dict[str, Any]] = None) ->
SelectSelectorConfig(
options=[
SelectOptionDict(value="add", label="Add counter"),
SelectOptionDict(value="edit", label="Edit counter"),
SelectOptionDict(value="delete", label="Delete counter"),
SelectOptionDict(value="finish", label="Finish setup")
],
Expand Down Expand Up @@ -85,25 +90,91 @@ async def async_step_trigger_state(self, user_input: Optional[Dict[str, Any]] =
return self.async_show_form(
step_id="trigger_state",
data_schema={
"trigger_state": SelectSelector(
"trigger_state": str
},
)

async def async_step_select_edit(self, user_input: Optional[Dict[str, Any]] = None) -> config_entries.FlowResult:
"""Step to select a counter to edit."""
if not self._counters:
return await self.async_step_init()

if user_input is not None:
selected_name = user_input["edit_target"]
# Find the counter index by name
for idx, counter in enumerate(self._counters):
if counter["name"] == selected_name:
self._selected_edit_index = idx
self._editing_counter = dict(counter)
return await self.async_step_edit_trigger_entity()
# If not found, go back to init
return await self.async_step_init()

return self.async_show_form(
step_id="select_edit",
data_schema={
"edit_target": SelectSelector(
SelectSelectorConfig(
options=[
SelectOptionDict(value="on", label="on"),
SelectOptionDict(value="off", label="off"),
SelectOptionDict(value="home", label="home"),
SelectOptionDict(value="not_home", label="not_home"),
SelectOptionDict(value="open", label="open"),
SelectOptionDict(value="closed", label="closed"),
SelectOptionDict(value="idle", label="idle"),
SelectOptionDict(value="playing", label="playing")
SelectOptionDict(value=c["name"], label=c["name"])
for c in self._counters
],
multiple=False,
mode=SelectSelectorMode.DROPDOWN
)
)
},
)

async def async_step_edit_trigger_entity(self, user_input: Optional[Dict[str, Any]] = None) -> config_entries.FlowResult:
"""Step to edit the trigger entity."""
if user_input is not None:
self._editing_counter["trigger_entity"] = user_input["trigger_entity"]
return await self.async_step_edit_trigger_state()

# Get current trigger entity value
current_entity = self._editing_counter.get("trigger_entity", "")

return self.async_show_form(
step_id="edit_trigger_entity",
data_schema={
"trigger_entity": EntitySelector(
EntitySelectorConfig()
)
},
description_placeholders={
"current_value": current_entity,
"counter_name": self._editing_counter.get("name", "")
}
)

async def async_step_edit_trigger_state(self, user_input: Optional[Dict[str, Any]] = None) -> config_entries.FlowResult:
"""Step to edit the trigger state."""
if user_input is not None:
self._editing_counter["trigger_state"] = user_input["trigger_state"]
# Update the counter in the list
if self._selected_edit_index is not None and 0 <= self._selected_edit_index < len(self._counters):
self._counters[self._selected_edit_index] = self._editing_counter

# Reset editing state
self._selected_edit_index = None
self._editing_counter = {}

return await self.async_step_init()

# Get current trigger state value
current_state = self._editing_counter.get("trigger_state", "")

return self.async_show_form(
step_id="edit_trigger_state",
data_schema={
"trigger_state": str
},
description_placeholders={
"current_value": current_state,
"counter_name": self._editing_counter.get("name", "")
}
)

async def async_step_select_delete(self, user_input: Optional[Dict[str, Any]] = None) -> config_entries.FlowResult:
"""Step to select a counter to delete."""
if not self._counters:
Expand Down
23 changes: 22 additions & 1 deletion custom_components/ha_daily_counter/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,32 @@
"step": {
"init": {
"title": "Manage Counters",
"description": "Add or remove counters used by this integration.",
"description": "Add, edit, or remove counters used by this integration.",
"data": {
"action": "Choose an action"
}
},
"select_edit": {
"title": "Edit Counter",
"description": "Select the counter you want to edit.",
"data": {
"edit_target": "Counter"
}
},
"edit_trigger_entity": {
"title": "Edit Trigger Entity",
"description": "Editing counter: {counter_name}\nCurrent entity: {current_value}\n\nSelect the new trigger entity:",
"data": {
"trigger_entity": "Trigger Entity"
}
},
"edit_trigger_state": {
"title": "Edit Trigger State",
"description": "Editing counter: {counter_name}\nCurrent state: {current_value}\n\nSelect the new trigger state:",
"data": {
"trigger_state": "Trigger State"
}
},
"select_delete": {
"title": "Delete Counter",
"description": "Select the counter you want to delete.",
Expand Down
Loading