Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional test fixture collection to enphase_envoy diagnostic report #116242

Open
wants to merge 25 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f1748db
diagnostics_fixtures
catsmanac Apr 26, 2024
32fe8a8
Merge branch 'dev' into dignostics_fixtures
catsmanac Apr 27, 2024
e621938
Merge branch 'dev' into dignostics_fixtures
catsmanac Apr 28, 2024
06dd30b
Merge branch 'dev' into dignostics_fixtures
catsmanac Apr 29, 2024
ff327b4
Merge branch 'dev' into dignostics_fixtures
catsmanac Apr 30, 2024
a966c70
Merge branch 'dev' into dignostics_fixtures
catsmanac May 1, 2024
6a6fed3
Merge branch 'dev' into dignostics_fixtures
catsmanac May 2, 2024
15b4b4a
Merge branch 'dev' into dignostics_fixtures
catsmanac May 2, 2024
fd0a5a8
Merge branch 'dev' into dignostics_fixtures
catsmanac May 3, 2024
05847e1
Merge branch 'dev' into dignostics_fixtures
catsmanac May 4, 2024
36f86dc
Merge branch 'dev' into dignostics_fixtures
catsmanac May 6, 2024
a204879
Merge branch 'dev' into dignostics_fixtures
catsmanac May 9, 2024
ae08cad
Merge branch 'dev' into dignostics_fixtures
catsmanac May 11, 2024
3befc54
Merge branch 'dev' into dignostics_fixtures
catsmanac May 13, 2024
8ba5a63
Merge branch 'dev' into dignostics_fixtures
catsmanac May 16, 2024
7619afe
Merge branch 'dev' into dignostics_fixtures
catsmanac May 17, 2024
97cfa07
Merge branch 'dev' into dignostics_fixtures
catsmanac May 18, 2024
dbc7265
Merge branch 'dev' into dignostics_fixtures
catsmanac May 19, 2024
7d7b6f5
Merge branch 'dev' into dignostics_fixtures
catsmanac May 21, 2024
b74d37a
Merge branch 'dev' into dignostics_fixtures
catsmanac May 26, 2024
e19345b
fix codespell errors
catsmanac May 26, 2024
c31befa
Merge branch 'dev' into dignostics_fixtures
catsmanac May 27, 2024
a595572
Merge branch 'dev' into dignostics_fixtures
catsmanac May 27, 2024
e4652ea
fix merge order and typo
catsmanac May 27, 2024
6a4953f
Merge branch 'dev' into dignostics_fixtures
catsmanac May 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 48 additions & 2 deletions homeassistant/components/enphase_envoy/config_flow.py
Expand Up @@ -12,12 +12,22 @@
import voluptuous as vol

from homeassistant.components import zeroconf
from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
from homeassistant.config_entries import (
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlowWithConfigEntry,
)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.httpx_client import get_async_client

from .const import DOMAIN, INVALID_AUTH_ERRORS
from .const import (
DOMAIN,
INVALID_AUTH_ERRORS,
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES,
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES_DEFAULT_VALUE,
)

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -50,6 +60,12 @@ def __init__(self) -> None:
self.protovers: str | None = None
self._reauth_entry: ConfigEntry | None = None

@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> EnvoyOptionsFlowHandler:
"""Options flow handler for Enphase_Envoy."""
return EnvoyOptionsFlowHandler(config_entry)

@callback
def _async_generate_schema(self) -> vol.Schema:
"""Generate schema."""
Expand Down Expand Up @@ -282,3 +298,33 @@ async def async_step_reconfigure(
description_placeholders=description_placeholders,
errors=errors,
)


class EnvoyOptionsFlowHandler(OptionsFlowWithConfigEntry):
"""Envoy config flow options handler."""

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)

return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Required(
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES,
default=self.config_entry.options.get(
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES,
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES_DEFAULT_VALUE,
),
): bool,
}
),
description_placeholders={
CONF_SERIAL: self.config_entry.unique_id,
CONF_HOST: self.config_entry.data.get("host"),
},
)
3 changes: 3 additions & 0 deletions homeassistant/components/enphase_envoy/const.py
Expand Up @@ -15,3 +15,6 @@
]

INVALID_AUTH_ERRORS = (EnvoyAuthenticationError, EnvoyAuthenticationRequired)

OPTION_DIAGNOSTICS_INCLUDE_FIXTURES = "diagnostics_include_fixtures"
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES_DEFAULT_VALUE = False
52 changes: 51 additions & 1 deletion homeassistant/components/enphase_envoy/diagnostics.py
Expand Up @@ -6,6 +6,8 @@
from typing import TYPE_CHECKING, Any

from attr import asdict
from pyenphase.envoy import Envoy
from pyenphase.exceptions import EnvoyError

from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
Expand All @@ -21,7 +23,7 @@
from homeassistant.helpers.json import json_dumps
from homeassistant.util.json import json_loads

from .const import DOMAIN
from .const import DOMAIN, OPTION_DIAGNOSTICS_INCLUDE_FIXTURES
from .coordinator import EnphaseUpdateCoordinator

CONF_TITLE = "title"
Expand All @@ -38,6 +40,46 @@
}


async def _get_fixture_collection(envoy: Envoy, serial: str) -> dict[str, Any]:
"""Collect Envoy endpoints to use for test fixture set."""
fixture_data: dict[str, Any] = {}
end_points = [
"/info",
"/api/v1/production",
"/api/v1/production/inverters",
"/production.json",
"/production.json?details=1",
"/production",
"/ivp/ensemble/power",
"/ivp/ensemble/inventory",
"/ivp/ensemble/dry_contacts",
"/ivp/ensemble/status",
"/ivp/ensemble/secctrl",
"/ivp/ss/dry_contact_settings",
"/admin/lib/tariff",
"/ivp/ss/gen_config",
"/ivp/ss/gen_schedule",
"/ivp/sc/pvlimit",
"/ivp/ss/pel_settings",
"/ivp/ensemble/generator",
"/ivp/meters",
"/ivp/meters/readings",
]

for end_point in end_points:
response = await envoy.request(end_point)
fixture_data[end_point] = response.text.replace("\n", "").replace(
serial, CLEAN_TEXT
)
fixture_data[f"{end_point}_log"] = json_dumps(
{
"headers": dict(response.headers.items()),
"code": response.status_code,
}
)
return fixture_data


async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry
) -> dict[str, Any]:
Expand Down Expand Up @@ -113,12 +155,20 @@ async def async_get_config_entry_diagnostics(
"ct_storage_meter": envoy.storage_meter_type,
}

fixture_data: dict[str, Any] = {}
if entry.options.get(OPTION_DIAGNOSTICS_INCLUDE_FIXTURES, False):
try:
fixture_data = await _get_fixture_collection(envoy=envoy, serial=old_serial)
except EnvoyError as err:
fixture_data["Error"] = repr(err)

diagnostic_data: dict[str, Any] = {
"config_entry": async_redact_data(entry.as_dict(), TO_REDACT),
"envoy_properties": envoy_properties,
"raw_data": json_loads(coordinator_data_cleaned),
"envoy_model_data": envoy_model,
"envoy_entities_by_device": json_loads(device_entities_cleaned),
"fixtures": fixture_data,
}

return diagnostic_data
10 changes: 10 additions & 0 deletions homeassistant/components/enphase_envoy/strings.json
Expand Up @@ -36,6 +36,16 @@
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"options": {
"step": {
"init": {
"title": "Envoy {serial} {host} options",
"data": {
"diagnostics_include_fixtures": "Include test fixture data in diagnostic report. Use when requested to provide test data for troubleshooting or development activies. With this option enabled the diagnostic report may take more time to download. When report is created best disable this option again."
}
}
}
},
"entity": {
"binary_sensor": {
"communicating": {
Expand Down
13 changes: 12 additions & 1 deletion tests/components/enphase_envoy/conftest.py
Expand Up @@ -339,11 +339,22 @@ def mock_envoy_fixture(
raw={"varies_by": "firmware_version"},
)
mock_envoy.update = AsyncMock(return_value=mock_envoy.data)

response = Mock()
response.status_code = 200
response.text = "Testing request \nreplies."
response.headers = {"Hello": "World"}
mock_envoy.request = AsyncMock(return_value=response)

return mock_envoy


@pytest.fixture(name="setup_enphase_envoy")
async def setup_enphase_envoy_fixture(hass: HomeAssistant, config, mock_envoy):
async def setup_enphase_envoy_fixture(
hass: HomeAssistant,
config,
mock_envoy,
):
"""Define a fixture to set up Enphase Envoy."""
with (
patch(
Expand Down