mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Add more sensors to openevse (#160904)
Co-authored-by: Joostlek <joostlek@outlook.com>
This commit is contained in:
@@ -10,6 +10,8 @@ from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
||||
from .coordinator import OpenEVSEConfigEntry, OpenEVSEDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: OpenEVSEConfigEntry) -> bool:
|
||||
"""Set up OpenEVSE from a config entry."""
|
||||
@@ -29,10 +31,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: OpenEVSEConfigEntry) ->
|
||||
|
||||
entry.runtime_data = coordinator
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, [Platform.SENSOR])
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: OpenEVSEConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
return await hass.config_entries.async_unload_platforms(entry, [Platform.SENSOR])
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
from openevsehttp.__main__ import OpenEVSE
|
||||
@@ -22,7 +23,15 @@ from homeassistant.const import (
|
||||
ATTR_SERIAL_NUMBER,
|
||||
CONF_HOST,
|
||||
CONF_MONITORED_VARIABLES,
|
||||
PERCENTAGE,
|
||||
SIGNAL_STRENGTH_DECIBELS,
|
||||
EntityCategory,
|
||||
UnitOfElectricCurrent,
|
||||
UnitOfElectricPotential,
|
||||
UnitOfEnergy,
|
||||
UnitOfInformation,
|
||||
UnitOfLength,
|
||||
UnitOfPower,
|
||||
UnitOfTemperature,
|
||||
UnitOfTime,
|
||||
)
|
||||
@@ -49,15 +58,30 @@ PARALLEL_UPDATES = 0
|
||||
class OpenEVSESensorDescription(SensorEntityDescription):
|
||||
"""Describes an OpenEVSE sensor entity."""
|
||||
|
||||
value_fn: Callable[[OpenEVSE], str | float | None]
|
||||
value_fn: Callable[[OpenEVSE], str | float | datetime | None]
|
||||
|
||||
|
||||
SENSOR_TYPES: tuple[OpenEVSESensorDescription, ...] = (
|
||||
# Status sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="status",
|
||||
translation_key="status",
|
||||
value_fn=lambda ev: ev.status,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="service_level",
|
||||
translation_key="service_level",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=["level_1", "level_2", "automatic"],
|
||||
value_fn=lambda ev: {
|
||||
"1": "level_1",
|
||||
"2": "level_2",
|
||||
"a": "automatic",
|
||||
}.get(ev.service_level.lower()),
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
# Timing sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="charge_time",
|
||||
translation_key="charge_time",
|
||||
@@ -67,6 +91,80 @@ SENSOR_TYPES: tuple[OpenEVSESensorDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.charge_time_elapsed,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="vehicle_eta",
|
||||
translation_key="vehicle_eta",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
value_fn=lambda ev: ev.vehicle_eta,
|
||||
),
|
||||
# Electrical sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="charging_current",
|
||||
translation_key="charging_current",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.charging_current,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="charging_voltage",
|
||||
translation_key="charging_voltage",
|
||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||
device_class=SensorDeviceClass.VOLTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.charging_voltage,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="charging_power",
|
||||
translation_key="charging_power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.charging_power,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="current_power",
|
||||
translation_key="current_power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.current_power,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="current_capacity",
|
||||
translation_key="current_capacity",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.current_capacity,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="max_current",
|
||||
translation_key="max_current",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda ev: ev.max_current,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="min_amps",
|
||||
translation_key="min_amps",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.min_amps,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="max_amps",
|
||||
translation_key="max_amps",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.max_amps,
|
||||
),
|
||||
# Temperature sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="ambient_temp",
|
||||
translation_key="ambient_temp",
|
||||
@@ -93,6 +191,17 @@ SENSOR_TYPES: tuple[OpenEVSESensorDescription, ...] = (
|
||||
value_fn=lambda ev: ev.rtc_temperature,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="esp_temp",
|
||||
translation_key="esp_temp",
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.esp_temperature,
|
||||
),
|
||||
# Energy sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="usage_session",
|
||||
translation_key="usage_session",
|
||||
@@ -111,6 +220,145 @@ SENSOR_TYPES: tuple[OpenEVSESensorDescription, ...] = (
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
value_fn=lambda ev: ev.usage_total,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="total_day",
|
||||
translation_key="total_day",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.total_day,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="total_week",
|
||||
translation_key="total_week",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.total_week,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="total_month",
|
||||
translation_key="total_month",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.total_month,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="total_year",
|
||||
translation_key="total_year",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.total_year,
|
||||
),
|
||||
# Vehicle sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="vehicle_soc",
|
||||
translation_key="vehicle_soc",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
device_class=SensorDeviceClass.BATTERY,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.vehicle_soc,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="vehicle_range",
|
||||
translation_key="vehicle_range",
|
||||
native_unit_of_measurement=UnitOfLength.KILOMETERS,
|
||||
device_class=SensorDeviceClass.DISTANCE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value_fn=lambda ev: ev.vehicle_range,
|
||||
),
|
||||
# Connectivity sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="wifi_signal",
|
||||
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS,
|
||||
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.wifi_signal,
|
||||
),
|
||||
# Power shaper sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="shaper_live_power",
|
||||
translation_key="shaper_live_power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.shaper_live_power,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="shaper_available_current",
|
||||
translation_key="shaper_available_current",
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.shaper_available_current,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="shaper_max_power",
|
||||
translation_key="shaper_max_power",
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.shaper_max_power,
|
||||
),
|
||||
# Safety trip count sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="gfi_trip_count",
|
||||
translation_key="gfi_trip_count",
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.gfi_trip_count,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="no_gnd_trip_count",
|
||||
translation_key="no_gnd_trip_count",
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.no_gnd_trip_count,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="stuck_relay_trip_count",
|
||||
translation_key="stuck_relay_trip_count",
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.stuck_relay_trip_count,
|
||||
),
|
||||
# System diagnostic sensors
|
||||
OpenEVSESensorDescription(
|
||||
key="uptime",
|
||||
translation_key="uptime",
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.uptime,
|
||||
),
|
||||
OpenEVSESensorDescription(
|
||||
key="freeram",
|
||||
translation_key="freeram",
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda ev: ev.freeram,
|
||||
),
|
||||
)
|
||||
|
||||
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
|
||||
@@ -217,6 +465,6 @@ class OpenEVSESensor(CoordinatorEntity[OpenEVSEDataUpdateCoordinator], SensorEnt
|
||||
self._attr_device_info[ATTR_SERIAL_NUMBER] = unique_id
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
def native_value(self) -> StateType | datetime:
|
||||
"""Return the state of the sensor."""
|
||||
return self.entity_description.value_fn(self.coordinator.charger)
|
||||
|
||||
@@ -34,23 +34,118 @@
|
||||
"ambient_temp": {
|
||||
"name": "Ambient temperature"
|
||||
},
|
||||
"available_current": {
|
||||
"name": "Available current"
|
||||
},
|
||||
"charge_rate": {
|
||||
"name": "Charge rate"
|
||||
},
|
||||
"charge_time": {
|
||||
"name": "Charge time elapsed"
|
||||
},
|
||||
"charging_current": {
|
||||
"name": "Charging current"
|
||||
},
|
||||
"charging_power": {
|
||||
"name": "Charging power"
|
||||
},
|
||||
"charging_voltage": {
|
||||
"name": "Charging voltage"
|
||||
},
|
||||
"current_capacity": {
|
||||
"name": "Current capacity"
|
||||
},
|
||||
"current_power": {
|
||||
"name": "Current power"
|
||||
},
|
||||
"esp_temp": {
|
||||
"name": "ESP temperature"
|
||||
},
|
||||
"freeram": {
|
||||
"name": "Free memory"
|
||||
},
|
||||
"gfi_trip_count": {
|
||||
"name": "GFCI trip count"
|
||||
},
|
||||
"ir_temp": {
|
||||
"name": "IR temperature"
|
||||
},
|
||||
"max_amps": {
|
||||
"name": "Maximum amperage"
|
||||
},
|
||||
"max_current": {
|
||||
"name": "Maximum current"
|
||||
},
|
||||
"min_amps": {
|
||||
"name": "Minimum amperage"
|
||||
},
|
||||
"mode": {
|
||||
"name": "Mode"
|
||||
},
|
||||
"no_gnd_trip_count": {
|
||||
"name": "No ground trip count"
|
||||
},
|
||||
"ota_update": {
|
||||
"name": "OTA update"
|
||||
},
|
||||
"rtc_temp": {
|
||||
"name": "RTC temperature"
|
||||
},
|
||||
"service_level": {
|
||||
"name": "Service level",
|
||||
"state": {
|
||||
"automatic": "Automatic",
|
||||
"level_1": "Level 1 (120V)",
|
||||
"level_2": "Level 2 (240V)"
|
||||
}
|
||||
},
|
||||
"shaper_available_current": {
|
||||
"name": "Shaper available current"
|
||||
},
|
||||
"shaper_live_power": {
|
||||
"name": "Shaper live power"
|
||||
},
|
||||
"shaper_max_power": {
|
||||
"name": "Shaper maximum power"
|
||||
},
|
||||
"smoothed_available_current": {
|
||||
"name": "Smoothed available current"
|
||||
},
|
||||
"status": {
|
||||
"name": "Charging status"
|
||||
},
|
||||
"stuck_relay_trip_count": {
|
||||
"name": "Stuck relay trip count"
|
||||
},
|
||||
"total_day": {
|
||||
"name": "Daily energy usage"
|
||||
},
|
||||
"total_month": {
|
||||
"name": "Monthly energy usage"
|
||||
},
|
||||
"total_week": {
|
||||
"name": "Weekly energy usage"
|
||||
},
|
||||
"total_year": {
|
||||
"name": "Yearly energy usage"
|
||||
},
|
||||
"uptime": {
|
||||
"name": "Uptime"
|
||||
},
|
||||
"usage_session": {
|
||||
"name": "Usage this session"
|
||||
},
|
||||
"usage_total": {
|
||||
"name": "Total energy usage"
|
||||
},
|
||||
"vehicle_eta": {
|
||||
"name": "Vehicle charge completion"
|
||||
},
|
||||
"vehicle_range": {
|
||||
"name": "Vehicle range"
|
||||
},
|
||||
"vehicle_soc": {
|
||||
"name": "Vehicle state of charge"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -26,19 +26,64 @@ def mock_charger() -> Generator[MagicMock]:
|
||||
):
|
||||
charger = mock.return_value
|
||||
charger.update = AsyncMock()
|
||||
charger.status = "Charging"
|
||||
charger.charge_time_elapsed = 3600 # 60 minutes in seconds
|
||||
charger.ambient_temperature = 25.5
|
||||
charger.ir_temperature = 30.2
|
||||
charger.rtc_temperature = 28.7
|
||||
charger.usage_session = 15000 # 15 kWh in Wh
|
||||
charger.usage_total = 500000 # 500 kWh in Wh
|
||||
charger.charging_current = 32.0
|
||||
charger.test_and_get = AsyncMock()
|
||||
charger.test_and_get.return_value = {
|
||||
"serial": "deadbeeffeed",
|
||||
"model": "openevse_wifi_v1",
|
||||
}
|
||||
# Status sensors
|
||||
charger.status = "Charging"
|
||||
charger.vehicle = True
|
||||
charger.mode = "STA"
|
||||
charger.charge_mode = "fast"
|
||||
charger.divertmode = "normal"
|
||||
charger.manual_override = False
|
||||
charger.ota_update = "none"
|
||||
charger.service_level = "2"
|
||||
# Timing sensors
|
||||
charger.charge_time_elapsed = 3600 # 60 minutes in seconds
|
||||
charger.vehicle_eta = None
|
||||
# Electrical sensors
|
||||
charger.charging_current = 32.0
|
||||
charger.charging_voltage = 240
|
||||
charger.charging_power = 7680.0
|
||||
charger.current_power = 7680
|
||||
charger.current_capacity = 32
|
||||
charger.max_current = 48
|
||||
charger.min_amps = 6
|
||||
charger.max_amps = 48
|
||||
# Divert/solar mode sensors
|
||||
charger.available_current = 32.0
|
||||
charger.smoothed_available_current = 32.0
|
||||
charger.charge_rate = 32.0
|
||||
# Temperature sensors
|
||||
charger.ambient_temperature = 25.5
|
||||
charger.ir_temperature = 30.2
|
||||
charger.rtc_temperature = 28.7
|
||||
charger.esp_temperature = 45.0
|
||||
# Energy sensors
|
||||
charger.usage_session = 15000 # 15 kWh in Wh
|
||||
charger.usage_total = 500000 # 500 kWh in Wh
|
||||
charger.total_day = 10000 # 10 kWh in Wh
|
||||
charger.total_week = 50000 # 50 kWh in Wh
|
||||
charger.total_month = 200000 # 200 kWh in Wh
|
||||
charger.total_year = 2000000 # 2000 kWh in Wh
|
||||
# Vehicle sensors
|
||||
charger.vehicle_soc = 75
|
||||
charger.vehicle_range = 250
|
||||
# Connectivity sensors
|
||||
charger.wifi_signal = -65
|
||||
# Power shaper sensors
|
||||
charger.shaper_live_power = 5000
|
||||
charger.shaper_available_current = 20.0
|
||||
charger.shaper_max_power = 11000
|
||||
# Safety trip count sensors
|
||||
charger.gfi_trip_count = 0
|
||||
charger.no_gnd_trip_count = 0
|
||||
charger.stuck_relay_trip_count = 0
|
||||
# System diagnostic sensors
|
||||
charger.uptime = 86400 # 1 day in seconds
|
||||
charger.freeram = 50000
|
||||
yield charger
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,13 @@
|
||||
"""Tests for the OpenEVSE sensor platform."""
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.openevse.const import DOMAIN
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import CONF_HOST, STATE_UNAVAILABLE
|
||||
from homeassistant.const import CONF_HOST, STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.setup import async_setup_component
|
||||
@@ -24,8 +24,9 @@ async def test_entities(
|
||||
mock_charger: MagicMock,
|
||||
) -> None:
|
||||
"""Test the sensor entities."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
with patch("homeassistant.components.openevse.PLATFORMS", [Platform.SENSOR]):
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
@@ -57,6 +58,28 @@ async def test_disabled_by_default_entities(
|
||||
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
|
||||
|
||||
|
||||
async def test_missing_sensor_graceful_handling(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_charger: MagicMock,
|
||||
) -> None:
|
||||
"""Test that missing sensor attributes are handled gracefully."""
|
||||
mock_charger.vehicle_soc = None
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
# The sensor with missing attribute should be unknown
|
||||
state = hass.states.get("sensor.openevse_mock_config_vehicle_state_of_charge")
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
# Other sensors should still work
|
||||
state = hass.states.get("sensor.openevse_mock_config_charging_status")
|
||||
assert state is not None
|
||||
assert state.state == "Charging"
|
||||
|
||||
|
||||
async def test_sensor_unavailable_on_coordinator_timeout(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
|
||||
Reference in New Issue
Block a user