1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-03 04:36:04 +01:00
Files
2026-06-15 15:43:53 +02:00

181 lines
6.1 KiB
Python

"""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.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_component import async_update_entity
from homeassistant.util import slugify
from .conftest import (
TEST_CURRENT_PAYLOAD_3PHASE,
TEST_CURRENT_PAYLOAD_SINGLE,
TEST_CURRENT_TOPIC,
TEST_POWER_PAYLOAD_CHARGING,
TEST_POWER_TOPIC,
TEST_SERIAL_NUMBER,
TEST_STATUS_PAYLOAD_CHARGING,
TEST_STATUS_PAYLOAD_CONNECTED,
TEST_STATUS_PAYLOAD_ERROR,
TEST_STATUS_PAYLOAD_ERROR_CAR,
TEST_STATUS_PAYLOAD_FINISHED,
TEST_STATUS_PAYLOAD_IDLE,
TEST_STATUS_PAYLOAD_UNAVAILABLE,
TEST_STATUS_PAYLOAD_WAITING_FOR_CAR,
TEST_STATUS_TOPIC,
TEST_VOLTAGE_PAYLOAD_NORMAL,
TEST_VOLTAGE_PAYLOAD_SINGLE,
TEST_VOLTAGE_TOPIC,
)
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(
hass: HomeAssistant,
setup_integration: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Verify all sensor states including single-phase charging and snapshots."""
prefix = f"sensor.{slugify(f'{GREENCELL_HABU_DEN} {TEST_SERIAL_NUMBER}')}"
curr_l1 = f"{prefix}_current_phase_l1"
curr_l2 = f"{prefix}_current_phase_l2"
volt_l1 = f"{prefix}_voltage_phase_l1"
volt_l2 = f"{prefix}_voltage_phase_l2"
async_fire_mqtt_message(hass, TEST_CURRENT_TOPIC, TEST_CURRENT_PAYLOAD_3PHASE)
async_fire_mqtt_message(hass, TEST_VOLTAGE_TOPIC, TEST_VOLTAGE_PAYLOAD_NORMAL)
await hass.async_block_till_done()
for eid in (curr_l1, curr_l2, volt_l1, volt_l2):
await async_update_entity(hass, eid)
assert hass.states.get(curr_l1).state == "2.0"
assert hass.states.get(curr_l2).state == "2.5"
assert hass.states.get(volt_l1).state == "230.0"
async_fire_mqtt_message(hass, TEST_CURRENT_TOPIC, TEST_CURRENT_PAYLOAD_SINGLE)
async_fire_mqtt_message(hass, TEST_VOLTAGE_TOPIC, TEST_VOLTAGE_PAYLOAD_SINGLE)
await hass.async_block_till_done()
for eid in (curr_l1, curr_l2, volt_l1, volt_l2):
await async_update_entity(hass, eid)
assert hass.states.get(curr_l1).state == "16.5"
assert hass.states.get(curr_l2).state == "0.0"
assert hass.states.get(volt_l2).state == "0.0"
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()
await async_update_entity(hass, f"{prefix}_status")
assert hass.states.get(curr_l1) == snapshot
async_fire_mqtt_message(hass, TEST_STATUS_TOPIC, TEST_STATUS_PAYLOAD_UNAVAILABLE)
await hass.async_block_till_done()
await async_update_entity(hass, curr_l1)
assert hass.states.get(curr_l1).state == STATE_UNAVAILABLE
@pytest.mark.parametrize(
("payload", "expected_state"),
[
(TEST_STATUS_PAYLOAD_IDLE, "idle"),
(TEST_STATUS_PAYLOAD_CONNECTED, "connected"),
(TEST_STATUS_PAYLOAD_CHARGING, "charging"),
(TEST_STATUS_PAYLOAD_FINISHED, "finished"),
(TEST_STATUS_PAYLOAD_ERROR, "error_evse"),
(TEST_STATUS_PAYLOAD_WAITING_FOR_CAR, "waiting_for_car"),
(TEST_STATUS_PAYLOAD_ERROR_CAR, "error_car"),
],
)
async def test_sensor_status_states(
hass: HomeAssistant,
setup_integration: MockConfigEntry,
payload: bytes,
expected_state: str,
) -> None:
"""Verify all possible status states using parametrization."""
prefix = f"sensor.{slugify(f'{GREENCELL_HABU_DEN} {TEST_SERIAL_NUMBER}')}"
status_id = f"{prefix}_status"
async_fire_mqtt_message(hass, TEST_STATUS_TOPIC, payload)
await hass.async_block_till_done()
await async_update_entity(hass, status_id)
await hass.async_block_till_done()
state = hass.states.get(status_id)
assert state is not None
assert state.state == expected_state
async def test_sensor_availability_and_errors(
hass: HomeAssistant,
setup_integration: MockConfigEntry,
) -> None:
"""Verify availability logic (UNAVAILABLE) and payload error handling."""
prefix = f"sensor.{slugify(f'{GREENCELL_HABU_DEN} {TEST_SERIAL_NUMBER}')}"
curr_l1 = f"{prefix}_current_phase_l1"
async_fire_mqtt_message(hass, TEST_STATUS_TOPIC, TEST_STATUS_PAYLOAD_UNAVAILABLE)
await hass.async_block_till_done()
await async_update_entity(hass, curr_l1)
state = hass.states.get(curr_l1)
assert state is not None
assert state.state == STATE_UNAVAILABLE