diff --git a/homeassistant/components/greencell/diagnostics.py b/homeassistant/components/greencell/diagnostics.py new file mode 100644 index 000000000000..bcc1cd12c65d --- /dev/null +++ b/homeassistant/components/greencell/diagnostics.py @@ -0,0 +1,31 @@ +"""Diagnostics support for the Greencell integration.""" + +from dataclasses import asdict +from typing import Any + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.core import HomeAssistant + +from .const import CONF_SERIAL_NUMBER +from .models import GreencellConfigEntry + +TO_REDACT = {CONF_SERIAL_NUMBER} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: GreencellConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + runtime_data = entry.runtime_data + + return { + "entry_data": async_redact_data(entry.data, TO_REDACT), + "access": { + "disabled": runtime_data.access.is_disabled(), + "can_execute": runtime_data.access.can_execute(), + }, + "current": asdict(runtime_data.current_data), + "voltage": asdict(runtime_data.voltage_data), + "power": asdict(runtime_data.power_data), + "state": asdict(runtime_data.state_data), + } diff --git a/homeassistant/components/greencell/quality_scale.yaml b/homeassistant/components/greencell/quality_scale.yaml index ee5d81a13a29..06e0031a63ad 100644 --- a/homeassistant/components/greencell/quality_scale.yaml +++ b/homeassistant/components/greencell/quality_scale.yaml @@ -42,7 +42,7 @@ rules: # Gold devices: done - diagnostics: todo + diagnostics: done discovery-update-info: todo discovery: todo docs-data-update: done diff --git a/tests/components/greencell/conftest.py b/tests/components/greencell/conftest.py index 931010ea0932..e666f22a52e8 100644 --- a/tests/components/greencell/conftest.py +++ b/tests/components/greencell/conftest.py @@ -5,15 +5,19 @@ from unittest.mock import patch import pytest +from homeassistant.components import mqtt as real_mqtt from homeassistant.components.greencell.const import ( CONF_SERIAL_NUMBER, DOMAIN, GREENCELL_BROADCAST_TOPIC, GREENCELL_DISC_TOPIC, ) +from homeassistant.components.mqtt import ReceiveMessage +from homeassistant.core import HomeAssistant from homeassistant.helpers.service_info.mqtt import MqttServiceInfo from tests.common import MockConfigEntry +from tests.typing import MqttMockHAClient # Test constants TEST_SERIAL_NUMBER = "EVGC021A22750001ZM0001" @@ -101,3 +105,42 @@ def mock_setup_entry(): return_value=True, ) as mock_setup: yield mock_setup + + +@pytest.fixture +async def setup_integration( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mqtt_mock: MqttMockHAClient, +) -> MockConfigEntry: + """Set up the greencell integration with device-ready fired synchronously.""" + + mock_config_entry.add_to_hass(hass) + real_async_subscribe = real_mqtt.async_subscribe + + async def _mock_init_subscribe(hass_arg, topic, msg_callback, *args, **kwargs): + """Fire discovery payload immediately, pass everything else through.""" + if topic == GREENCELL_DISC_TOPIC: + msg_callback( + ReceiveMessage( + topic=GREENCELL_DISC_TOPIC, + payload=f'{{"id": "{TEST_SERIAL_NUMBER}"}}', + qos=0, + retain=False, + subscribed_topic=GREENCELL_DISC_TOPIC, + timestamp=time.time(), + ) + ) + return lambda: None + return await real_async_subscribe( + hass_arg, topic, msg_callback, *args, **kwargs + ) + + with patch( + "homeassistant.components.greencell.mqtt.async_subscribe", + side_effect=_mock_init_subscribe, + ): + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + return mock_config_entry diff --git a/tests/components/greencell/snapshots/test_diagnostics.ambr b/tests/components/greencell/snapshots/test_diagnostics.ambr new file mode 100644 index 000000000000..a367e0d550da --- /dev/null +++ b/tests/components/greencell/snapshots/test_diagnostics.ambr @@ -0,0 +1,28 @@ +# serializer version: 1 +# name: test_diagnostics + dict({ + 'access': dict({ + 'can_execute': True, + 'disabled': False, + }), + 'current': dict({ + 'l1': 2000, + 'l2': 2500, + 'l3': 3000, + }), + 'entry_data': dict({ + 'serial_number': '**REDACTED**', + }), + 'power': dict({ + 'value': 1500.5, + }), + 'state': dict({ + 'value': 'CHARGING', + }), + 'voltage': dict({ + 'l1': 230.0, + 'l2': 229.7, + 'l3': 232.5, + }), + }) +# --- diff --git a/tests/components/greencell/test_diagnostics.py b/tests/components/greencell/test_diagnostics.py new file mode 100644 index 000000000000..5621e5e86132 --- /dev/null +++ b/tests/components/greencell/test_diagnostics.py @@ -0,0 +1,39 @@ +"""Tests for the Greencell diagnostics.""" + +from syrupy.assertion import SnapshotAssertion + +from homeassistant.core import HomeAssistant + +from .conftest import ( + TEST_CURRENT_PAYLOAD_3PHASE, + TEST_CURRENT_TOPIC, + TEST_POWER_PAYLOAD_CHARGING, + TEST_POWER_TOPIC, + TEST_STATUS_PAYLOAD_CHARGING, + TEST_STATUS_TOPIC, + TEST_VOLTAGE_PAYLOAD_NORMAL, + TEST_VOLTAGE_TOPIC, +) + +from tests.common import MockConfigEntry, async_fire_mqtt_message +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + setup_integration: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test config entry diagnostics.""" + async_fire_mqtt_message(hass, TEST_CURRENT_TOPIC, TEST_CURRENT_PAYLOAD_3PHASE) + async_fire_mqtt_message(hass, TEST_VOLTAGE_TOPIC, TEST_VOLTAGE_PAYLOAD_NORMAL) + async_fire_mqtt_message(hass, TEST_POWER_TOPIC, TEST_POWER_PAYLOAD_CHARGING) + async_fire_mqtt_message(hass, TEST_STATUS_TOPIC, TEST_STATUS_PAYLOAD_CHARGING) + await hass.async_block_till_done() + + assert ( + await get_diagnostics_for_config_entry(hass, hass_client, setup_integration) + == snapshot + ) diff --git a/tests/components/greencell/test_sensor.py b/tests/components/greencell/test_sensor.py index 32858964e80c..10909a47da6f 100644 --- a/tests/components/greencell/test_sensor.py +++ b/tests/components/greencell/test_sensor.py @@ -1,17 +1,9 @@ """Real integration tests for Greencell EVSE sensors.""" -import time -from unittest.mock import patch - import pytest from syrupy.assertion import SnapshotAssertion -from homeassistant.components import mqtt as real_mqtt -from homeassistant.components.greencell.const import ( - GREENCELL_DISC_TOPIC, - GREENCELL_HABU_DEN, -) -from homeassistant.components.mqtt import ReceiveMessage +from homeassistant.components.greencell.const import GREENCELL_HABU_DEN from homeassistant.const import STATE_UNAVAILABLE from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_component import async_update_entity @@ -39,46 +31,6 @@ from .conftest import ( ) from tests.common import MockConfigEntry, async_fire_mqtt_message -from tests.typing import MqttMockHAClient - - -@pytest.fixture -async def setup_integration( - hass: HomeAssistant, - mock_config_entry: MockConfigEntry, - mqtt_mock: MqttMockHAClient, -): - """Set up the greencell integration with device-ready fired synchronously.""" - - mock_config_entry.add_to_hass(hass) - real_async_subscribe = real_mqtt.async_subscribe - - async def _mock_init_subscribe(hass_arg, topic, msg_callback, *args, **kwargs): - """Fire discovery payload immediately, pass everything else through.""" - if topic == GREENCELL_DISC_TOPIC: - msg_callback( - ReceiveMessage( - topic=GREENCELL_DISC_TOPIC, - payload=f'{{"id": "{TEST_SERIAL_NUMBER}"}}', - qos=0, - retain=False, - subscribed_topic=GREENCELL_DISC_TOPIC, - timestamp=time.time(), - ) - ) - return lambda: None - return await real_async_subscribe( - hass_arg, topic, msg_callback, *args, **kwargs - ) - - with patch( - "homeassistant.components.greencell.mqtt.async_subscribe", - side_effect=_mock_init_subscribe, - ): - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - - return mock_config_entry async def test_sensor_states_and_snapshots(