Issues template function (#95206)
* Add 'issues' template function for listing active issues. * Add issue template function test * Add 'issue' template function for getting specific issue by domain and issue_id * Remove comment * Fix function description * Remove reduntant function, Fix tests * remove pass_context * remove issues filter Co-authored-by: Erik Montnemery <erik@montnemery.com> --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>pull/112198/head
parent
c2a991625d
commit
b381922a20
|
@ -78,7 +78,13 @@ from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads
|
||||||
from homeassistant.util.read_only_dict import ReadOnlyDict
|
from homeassistant.util.read_only_dict import ReadOnlyDict
|
||||||
from homeassistant.util.thread import ThreadWithException
|
from homeassistant.util.thread import ThreadWithException
|
||||||
|
|
||||||
from . import area_registry, device_registry, entity_registry, location as loc_helper
|
from . import (
|
||||||
|
area_registry,
|
||||||
|
device_registry,
|
||||||
|
entity_registry,
|
||||||
|
issue_registry,
|
||||||
|
location as loc_helper,
|
||||||
|
)
|
||||||
from .singleton import singleton
|
from .singleton import singleton
|
||||||
from .translation import async_translate_state
|
from .translation import async_translate_state
|
||||||
from .typing import TemplateVarsType
|
from .typing import TemplateVarsType
|
||||||
|
@ -1357,6 +1363,21 @@ def is_device_attr(
|
||||||
return bool(device_attr(hass, device_or_entity_id, attr_name) == attr_value)
|
return bool(device_attr(hass, device_or_entity_id, attr_name) == attr_value)
|
||||||
|
|
||||||
|
|
||||||
|
def issues(hass: HomeAssistant) -> dict[tuple[str, str], dict[str, Any]]:
|
||||||
|
"""Return all open issues."""
|
||||||
|
current_issues = issue_registry.async_get(hass).issues
|
||||||
|
# Use JSON for safe representation
|
||||||
|
return {k: v.to_json() for (k, v) in current_issues.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def issue(hass: HomeAssistant, domain: str, issue_id: str) -> dict[str, Any] | None:
|
||||||
|
"""Get issue by domain and issue_id."""
|
||||||
|
result = issue_registry.async_get(hass).async_get_issue(domain, issue_id)
|
||||||
|
if result:
|
||||||
|
return result.to_json()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def areas(hass: HomeAssistant) -> Iterable[str | None]:
|
def areas(hass: HomeAssistant) -> Iterable[str | None]:
|
||||||
"""Return all areas."""
|
"""Return all areas."""
|
||||||
area_reg = area_registry.async_get(hass)
|
area_reg = area_registry.async_get(hass)
|
||||||
|
@ -2619,6 +2640,11 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
||||||
self.globals["device_id"] = hassfunction(device_id)
|
self.globals["device_id"] = hassfunction(device_id)
|
||||||
self.filters["device_id"] = self.globals["device_id"]
|
self.filters["device_id"] = self.globals["device_id"]
|
||||||
|
|
||||||
|
self.globals["issues"] = hassfunction(issues)
|
||||||
|
|
||||||
|
self.globals["issue"] = hassfunction(issue)
|
||||||
|
self.filters["issue"] = self.globals["issue"]
|
||||||
|
|
||||||
self.globals["areas"] = hassfunction(areas)
|
self.globals["areas"] = hassfunction(areas)
|
||||||
|
|
||||||
self.globals["area_id"] = hassfunction(area_id)
|
self.globals["area_id"] = hassfunction(area_id)
|
||||||
|
|
|
@ -37,6 +37,7 @@ from homeassistant.helpers import (
|
||||||
device_registry as dr,
|
device_registry as dr,
|
||||||
entity,
|
entity,
|
||||||
entity_registry as er,
|
entity_registry as er,
|
||||||
|
issue_registry as ir,
|
||||||
template,
|
template,
|
||||||
translation,
|
translation,
|
||||||
)
|
)
|
||||||
|
@ -3512,6 +3513,67 @@ async def test_device_attr(
|
||||||
assert info.rate_limit is None
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_issues(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None:
|
||||||
|
"""Test issues function."""
|
||||||
|
# Test no issues
|
||||||
|
info = render_to_info(hass, "{{ issues() }}")
|
||||||
|
assert_result_info(info, {})
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test persistent issue
|
||||||
|
ir.async_create_issue(
|
||||||
|
hass,
|
||||||
|
"test",
|
||||||
|
"issue 1",
|
||||||
|
breaks_in_ha_version="2023.7",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=True,
|
||||||
|
learn_more_url="https://theuselessweb.com",
|
||||||
|
severity="error",
|
||||||
|
translation_key="abc_1234",
|
||||||
|
translation_placeholders={"abc": "123"},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
created_issue = issue_registry.async_get_issue("test", "issue 1")
|
||||||
|
info = render_to_info(hass, "{{ issues()['test', 'issue 1'] }}")
|
||||||
|
assert_result_info(info, created_issue.to_json())
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test fixed issue
|
||||||
|
ir.async_delete_issue(hass, "test", "issue 1")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
info = render_to_info(hass, "{{ issues() }}")
|
||||||
|
assert_result_info(info, {})
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_issue(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None:
|
||||||
|
"""Test issue function."""
|
||||||
|
# Test non existent issue
|
||||||
|
info = render_to_info(hass, "{{ issue('non_existent', 'issue') }}")
|
||||||
|
assert_result_info(info, None)
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
# Test existing issue
|
||||||
|
ir.async_create_issue(
|
||||||
|
hass,
|
||||||
|
"test",
|
||||||
|
"issue 1",
|
||||||
|
breaks_in_ha_version="2023.7",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=True,
|
||||||
|
learn_more_url="https://theuselessweb.com",
|
||||||
|
severity="error",
|
||||||
|
translation_key="abc_1234",
|
||||||
|
translation_placeholders={"abc": "123"},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
created_issue = issue_registry.async_get_issue("test", "issue 1")
|
||||||
|
info = render_to_info(hass, "{{ issue('test', 'issue 1') }}")
|
||||||
|
assert_result_info(info, created_issue.to_json())
|
||||||
|
assert info.rate_limit is None
|
||||||
|
|
||||||
|
|
||||||
async def test_areas(hass: HomeAssistant, area_registry: ar.AreaRegistry) -> None:
|
async def test_areas(hass: HomeAssistant, area_registry: ar.AreaRegistry) -> None:
|
||||||
"""Test areas function."""
|
"""Test areas function."""
|
||||||
# Test no areas
|
# Test no areas
|
||||||
|
|
Loading…
Reference in New Issue