Skip to content

Commit 6f6a0e6

Browse files
committed
Implement weather entity issue handling and repair flow
- Added functionality to create and delete issues related to weather entities that do not support hourly forecasts. - Introduced a new repair flow for users to select a new weather entity or remove the existing one. - Updated translations for the new repair options and issue descriptions in both English and French. - Refactored existing repair flow methods to accommodate the new structure and improve user experience.
1 parent 96c53bd commit 6f6a0e6

File tree

4 files changed

+109
-61
lines changed

4 files changed

+109
-61
lines changed

custom_components/heating_cooling_degree_days/coordinator.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ def __init__(
103103
weather_entity if weather_entity else "none",
104104
)
105105

106+
ir.async_delete_issue(
107+
self.hass,
108+
DOMAIN,
109+
ISSUE_WEATHER_NO_HOURLY_FORECAST,
110+
)
111+
112+
ir.async_create_issue(
113+
self.hass,
114+
DOMAIN,
115+
ISSUE_WEATHER_NO_HOURLY_FORECAST,
116+
is_fixable=True,
117+
is_persistent=True,
118+
severity=ir.IssueSeverity.ERROR,
119+
translation_key="weather_no_hourly_forecast",
120+
translation_placeholders={
121+
"entity_id": self.weather_entity,
122+
},
123+
data={
124+
"entry_id": self.entry_id,
125+
"entity_id": self.weather_entity,
126+
},
127+
)
128+
106129
async def async_load_stored_data(self):
107130
"""Load stored daily values from persistent storage."""
108131
try:
@@ -337,7 +360,8 @@ async def _async_update_data(self):
337360
result[SENSOR_TYPE_CDD_ESTIMATED_TOMORROW] = None
338361
else:
339362
# No weather entity configured, delete any existing issue
340-
ir.async_delete_issue(self.hass, DOMAIN, ISSUE_WEATHER_NO_HOURLY_FORECAST)
363+
# TODO: ir.async_delete_issue(self.hass, DOMAIN, ISSUE_WEATHER_NO_HOURLY_FORECAST)
364+
print("No weather entity configured, deleting issue")
341365

342366
return result
343367

@@ -440,7 +464,7 @@ async def _get_weather_forecast(self) -> list[dict] | None:
440464

441465
# If we successfully got forecast data, delete any existing issue
442466
# (in case it was fixed by changing the entity or the entity was updated)
443-
ir.async_delete_issue(self.hass, DOMAIN, ISSUE_WEATHER_NO_HOURLY_FORECAST)
467+
# TODO: ir.async_delete_issue(self.hass, DOMAIN, ISSUE_WEATHER_NO_HOURLY_FORECAST)
444468

445469
return forecast
446470

custom_components/heating_cooling_degree_days/repairs.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,20 @@ async def async_create_fix_flow(
2525
data: dict[str, str | int | float | None] | None,
2626
) -> RepairsFlow:
2727
"""Create flow."""
28-
if issue_id == ISSUE_WEATHER_NO_HOURLY_FORECAST:
29-
return WeatherEntityRepairFlow(hass, data)
3028

31-
return ConfirmRepairFlow()
29+
for repair_flow_cls in [WeatherNoHourlyForecastRepairFlow]:
30+
if repair_flow_cls.is_issue_supported(issue_id):
31+
return repair_flow_cls(hass, data)
3232

3333

34-
class WeatherEntityRepairFlow(RepairsFlow):
34+
class WeatherNoHourlyForecastRepairFlow(RepairsFlow):
3535
"""Handler for weather entity repair flow."""
3636

37+
@staticmethod
38+
def is_issue_supported(issue_id: str) -> bool:
39+
"""Return True if this flow supports the given issue_id."""
40+
return issue_id == ISSUE_WEATHER_NO_HOURLY_FORECAST
41+
3742
def __init__(
3843
self, hass: HomeAssistant, data: dict[str, str | int | float | None] | None
3944
) -> None:
@@ -45,6 +50,12 @@ def __init__(
4550

4651
async def async_step_init(
4752
self, user_input: dict[str, str] | None = None
53+
) -> data_entry_flow.FlowResult:
54+
"""Handle the first step of a fix flow."""
55+
return await self.async_step_weather_no_hourly_forecast(user_input)
56+
57+
async def async_step_weather_no_hourly_forecast(
58+
self, user_input: dict[str, str] | None = None
4859
) -> data_entry_flow.FlowResult:
4960
"""Handle the first step of a fix flow."""
5061
if not self.entry_id:
@@ -58,29 +69,24 @@ async def async_step_init(
5869
if user_input is not None:
5970
action = user_input.get("action")
6071
if action == "select_new":
61-
return await self.async_step_select_weather()
72+
return await self.async_step_weather_no_hourly_forecast_select_weather()
6273
elif action == "remove":
63-
return await self.async_step_confirm_remove()
74+
return await self.async_step_weather_no_hourly_forecast_confirm_remove()
6475

65-
# Show form to choose action
66-
return self.async_show_form(
67-
step_id="init",
68-
data_schema=vol.Schema(
69-
{
70-
vol.Required("action", default="select_new"): vol.In(
71-
{
72-
"select_new": "Select a new weather entity",
73-
"remove": "Remove weather entity (disable forecast sensors)",
74-
}
75-
),
76-
}
77-
),
76+
_LOGGER.debug("user_input: %s", user_input)
77+
78+
return self.async_show_menu(
79+
step_id="weather_no_hourly_forecast",
80+
menu_options=[
81+
"weather_no_hourly_forecast_select_weather",
82+
"weather_no_hourly_forecast_confirm_remove",
83+
],
7884
description_placeholders={
79-
"current_entity": self.current_entity or "unknown",
85+
"current_entity": self.current_entity,
8086
},
8187
)
8288

83-
async def async_step_select_weather(
89+
async def async_step_weather_no_hourly_forecast_select_weather(
8490
self, user_input: dict[str, str] | None = None
8591
) -> data_entry_flow.FlowResult:
8692
"""Handle the weather entity selection step."""
@@ -116,7 +122,7 @@ async def async_step_select_weather(
116122
return self.async_abort(reason="entry_not_found")
117123
else:
118124
return self.async_show_form(
119-
step_id="select_weather",
125+
step_id="weather_no_hourly_forecast_select_weather",
120126
data_schema=vol.Schema(
121127
{
122128
vol.Optional(CONF_WEATHER_ENTITY): selector.EntitySelector(
@@ -129,7 +135,7 @@ async def async_step_select_weather(
129135

130136
# Show form to select new weather entity
131137
return self.async_show_form(
132-
step_id="select_weather",
138+
step_id="weather_no_hourly_forecast_select_weather",
133139
data_schema=vol.Schema(
134140
{
135141
vol.Optional(CONF_WEATHER_ENTITY): selector.EntitySelector(
@@ -172,7 +178,7 @@ async def _validate_weather_entity(self, entity_id: str) -> bool:
172178
)
173179
return True
174180

175-
async def async_step_confirm_remove(
181+
async def async_step_weather_no_hourly_forecast_confirm_remove(
176182
self, user_input: dict[str, str] | None = None
177183
) -> data_entry_flow.FlowResult:
178184
"""Handle the confirmation step for removing weather entity."""
@@ -200,7 +206,7 @@ async def async_step_confirm_remove(
200206

201207
# Show confirmation form
202208
return self.async_show_form(
203-
step_id="confirm_remove",
209+
step_id="weather_no_hourly_forecast_confirm_remove",
204210
data_schema=vol.Schema({}),
205211
description_placeholders={
206212
"current_entity": self.current_entity or "unknown",

custom_components/heating_cooling_degree_days/translations/en.json

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,35 @@
3232
"base_temperature": "The default base temperature is 18°C for Celsius or 65°F for Fahrenheit, depending on your unit system",
3333
"weather_entity": "If provided, this weather entity enables forecast data for 24h and 48h estimates"
3434
}
35+
},
36+
"weather_no_hourly_forecast": {
37+
"title": "Fix weather entity issue",
38+
"description": "The weather entity '{current_entity}' no longer supports hourly forecasts. Choose how to fix this:",
39+
"data": {
40+
"action": "Action"
41+
},
42+
"menu_options": {
43+
"weather_no_hourly_forecast_select_weather": "Select new weather entity",
44+
"weather_no_hourly_forecast_confirm_remove": "Remove weather entity (disable forecast sensors)"
45+
}
46+
},
47+
"weather_no_hourly_forecast_select_weather": {
48+
"title": "Select new weather entity",
49+
"description": "Select a weather entity that supports hourly forecasts:",
50+
"data": {
51+
"weather_entity": "Weather Entity"
52+
}
53+
},
54+
"weather_no_hourly_forecast_confirm_remove": {
55+
"title": "Remove weather entity",
56+
"description": "This will remove the weather entity '{current_entity}' from the configuration and disable the forecast sensors (HDD Estimated Today/Tomorrow and CDD Estimated Today/Tomorrow if enabled)."
3557
}
3658
},
3759
"error": {
3860
"invalid_temperature_sensor": "Invalid temperature sensor. Please select a valid temperature sensor.",
39-
"invalid_weather_entity": "Invalid weather entity. Please select a valid weather entity with forecast data."
61+
"invalid_weather_entity": "Invalid weather entity. Please select a valid weather entity with forecast data.",
62+
"no_entry_id": "No entry ID provided",
63+
"entry_not_found": "Configuration entry not found"
4064
},
4165
"abort": {
4266
"reconfigure_successful": "Configuration updated successfully"
@@ -79,22 +103,7 @@
79103
"issues": {
80104
"weather_no_hourly_forecast": {
81105
"title": "Weather entity no longer supports hourly forecasts",
82-
"description": "The weather entity '{entity_id}' configured for this integration no longer supports hourly forecasts, which are required for estimated degree days calculations. Please select a different weather entity that supports hourly forecasts."
83-
}
84-
},
85-
"repairs": {
86-
"weather_no_hourly_forecast": {
87-
"init": {
88-
"title": "Fix weather entity issue",
89-
"description": "The weather entity '{current_entity}' no longer supports hourly forecasts. Choose how to fix this:",
90-
"data": {
91-
"action": "Action"
92-
}
93-
},
94-
"confirm_remove": {
95-
"title": "Remove weather entity",
96-
"description": "This will remove the weather entity '{current_entity}' from the configuration and disable the forecast sensors (HDD Estimated Today/Tomorrow and CDD Estimated Today/Tomorrow if enabled)."
97-
}
106+
"description": "The weather entity {entity_id} configured for this integration no longer supports hourly forecasts, which are required for estimated degree days calculations. Please select a different weather entity that supports hourly forecasts."
98107
}
99108
}
100109
}

custom_components/heating_cooling_degree_days/translations/fr.json

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,35 @@
3232
"base_temperature": "La température de base par défaut est de 18°C pour Celsius ou 65°F pour Fahrenheit, selon votre système d'unités",
3333
"weather_entity": "Si fournie, cette entité météo permet de fournir des données prévisionnelles à 24h et 48h"
3434
}
35+
},
36+
"weather_no_hourly_forecast": {
37+
"title": "Corriger le problème de l'entité météo",
38+
"description": "L'entité météo '{current_entity}' ne supporte plus les prévisions horaires. Choisissez comment corriger cela :",
39+
"data": {
40+
"action": "Action"
41+
},
42+
"menu_options": {
43+
"weather_no_hourly_forecast_select_weather": "Sélectionner une nouvelle entité météo",
44+
"weather_no_hourly_forecast_confirm_remove": "Supprimer l'entité météo (désactiver les capteurs de prévision)"
45+
}
46+
},
47+
"weather_no_hourly_forecast_select_weather": {
48+
"title": "Sélectionner une nouvelle entité météo",
49+
"description": "Sélectionnez une entité météo qui supporte les prévisions horaires :",
50+
"data": {
51+
"weather_entity": "Entité météo"
52+
}
53+
},
54+
"weather_no_hourly_forecast_confirm_remove": {
55+
"title": "Supprimer l'entité météo",
56+
"description": "Cela supprimera l'entité météo '{current_entity}' de la configuration et désactivera les capteurs de prévision (DJC Estimé Aujourd'hui/Demain et DJR Estimé Aujourd'hui/Demain si activés)."
3557
}
3658
},
3759
"error": {
3860
"invalid_temperature_sensor": "Capteur de température invalide. Veuillez sélectionner un capteur de température valide.",
39-
"invalid_weather_entity": "Entité météo invalide. Veuillez sélectionner une entité météo valide avec des données de prévision."
61+
"invalid_weather_entity": "Entité météo invalide. Veuillez sélectionner une entité météo valide avec des données de prévision.",
62+
"no_entry_id": "Aucun ID d'entrée fourni",
63+
"entry_not_found": "Entrée de configuration introuvable"
4064
},
4165
"abort": {
4266
"reconfigure_successful": "Configuration mise à jour avec succès"
@@ -79,22 +103,7 @@
79103
"issues": {
80104
"weather_no_hourly_forecast": {
81105
"title": "L'entité météo ne supporte plus les prévisions horaires",
82-
"description": "L'entité météo '{entity_id}' configurée pour cette intégration ne supporte plus les prévisions horaires, qui sont nécessaires pour les calculs de degrés-jours estimés. Veuillez sélectionner une autre entité météo qui supporte les prévisions horaires."
83-
}
84-
},
85-
"repairs": {
86-
"weather_no_hourly_forecast": {
87-
"init": {
88-
"title": "Corriger le problème de l'entité météo",
89-
"description": "L'entité météo '{current_entity}' ne supporte plus les prévisions horaires. Choisissez comment corriger cela :",
90-
"data": {
91-
"action": "Action"
92-
}
93-
},
94-
"confirm_remove": {
95-
"title": "Supprimer l'entité météo",
96-
"description": "Cela supprimera l'entité météo '{current_entity}' de la configuration et désactivera les capteurs de prévision (DJC Estimé Aujourd'hui/Demain et DJR Estimé Aujourd'hui/Demain si activés)."
97-
}
106+
"description": "L'entité météo {entity_id} configurée pour cette intégration ne supporte plus les prévisions horaires, qui sont nécessaires pour les calculs de degrés-jours estimés. Veuillez sélectionner une autre entité météo qui supporte les prévisions horaires."
98107
}
99108
}
100109
}

0 commit comments

Comments
 (0)