mirror of
https://github.com/home-assistant/core.git
synced 2026-04-17 15:44:52 +01:00
Add binary sensor platform and tests to NRGkick integration (#164629)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
@@ -11,6 +11,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from .coordinator import NRGkickConfigEntry, NRGkickDataUpdateCoordinator
|
||||
|
||||
PLATFORMS: list[Platform] = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.NUMBER,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
|
||||
76
homeassistant/components/nrgkick/binary_sensor.py
Normal file
76
homeassistant/components/nrgkick/binary_sensor.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""Binary sensor platform for NRGkick."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .coordinator import NRGkickConfigEntry, NRGkickData, NRGkickDataUpdateCoordinator
|
||||
from .entity import NRGkickEntity, get_nested_dict_value
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class NRGkickBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Class describing NRGkick binary sensor entities."""
|
||||
|
||||
is_on_fn: Callable[[NRGkickData], bool | None]
|
||||
|
||||
|
||||
BINARY_SENSORS: tuple[NRGkickBinarySensorEntityDescription, ...] = (
|
||||
NRGkickBinarySensorEntityDescription(
|
||||
key="charge_permitted",
|
||||
translation_key="charge_permitted",
|
||||
is_on_fn=lambda data: (
|
||||
bool(value)
|
||||
if (
|
||||
value := get_nested_dict_value(
|
||||
data.values, "general", "charge_permitted"
|
||||
)
|
||||
)
|
||||
is not None
|
||||
else None
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
_hass: HomeAssistant,
|
||||
entry: NRGkickConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up NRGkick binary sensors based on a config entry."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
NRGkickBinarySensor(coordinator, description) for description in BINARY_SENSORS
|
||||
)
|
||||
|
||||
|
||||
class NRGkickBinarySensor(NRGkickEntity, BinarySensorEntity):
|
||||
"""Representation of a NRGkick binary sensor."""
|
||||
|
||||
entity_description: NRGkickBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: NRGkickDataUpdateCoordinator,
|
||||
entity_description: NRGkickBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the binary sensor."""
|
||||
super().__init__(coordinator, entity_description.key)
|
||||
self.entity_description = entity_description
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Return the state of the binary sensor."""
|
||||
return self.entity_description.is_on_fn(self.coordinator.data)
|
||||
@@ -14,6 +14,17 @@ from .const import DOMAIN
|
||||
from .coordinator import NRGkickDataUpdateCoordinator
|
||||
|
||||
|
||||
def get_nested_dict_value(data: Any, *keys: str) -> Any:
|
||||
"""Safely get a nested value from dict-like API responses."""
|
||||
current: Any = data
|
||||
for key in keys:
|
||||
try:
|
||||
current = current.get(key)
|
||||
except AttributeError:
|
||||
return None
|
||||
return current
|
||||
|
||||
|
||||
class NRGkickEntity(CoordinatorEntity[NRGkickDataUpdateCoordinator]):
|
||||
"""Base class for NRGkick entities with common device info setup."""
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"entity": {
|
||||
"binary_sensor": {
|
||||
"charge_permitted": {
|
||||
"default": "mdi:ev-station"
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"current_set": {
|
||||
"default": "mdi:current-ac"
|
||||
|
||||
@@ -45,22 +45,11 @@ from .const import (
|
||||
WARNING_CODE_MAP,
|
||||
)
|
||||
from .coordinator import NRGkickConfigEntry, NRGkickData, NRGkickDataUpdateCoordinator
|
||||
from .entity import NRGkickEntity
|
||||
from .entity import NRGkickEntity, get_nested_dict_value
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
def _get_nested_dict_value(data: Any, *keys: str) -> Any:
|
||||
"""Safely get a nested value from dict-like API responses."""
|
||||
current: Any = data
|
||||
for key in keys:
|
||||
try:
|
||||
current = current.get(key)
|
||||
except AttributeError:
|
||||
return None
|
||||
return current
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class NRGkickSensorEntityDescription(SensorEntityDescription):
|
||||
"""Class describing NRGkick sensor entities."""
|
||||
@@ -159,7 +148,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.info, "general", "rated_current"
|
||||
),
|
||||
),
|
||||
@@ -167,7 +156,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
NRGkickSensorEntityDescription(
|
||||
key="connector_phase_count",
|
||||
translation_key="connector_phase_count",
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.info, "connector", "phase_count"
|
||||
),
|
||||
),
|
||||
@@ -178,7 +167,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.info, "connector", "max_current"
|
||||
),
|
||||
),
|
||||
@@ -189,7 +178,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
options=_enum_options_from_mapping(CONNECTOR_TYPE_MAP),
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(StateType, _get_nested_dict_value(data.info, "connector", "type")),
|
||||
cast(StateType, get_nested_dict_value(data.info, "connector", "type")),
|
||||
CONNECTOR_TYPE_MAP,
|
||||
),
|
||||
),
|
||||
@@ -198,7 +187,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
translation_key="connector_serial",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "connector", "serial"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "connector", "serial"),
|
||||
),
|
||||
# INFO - Grid
|
||||
NRGkickSensorEntityDescription(
|
||||
@@ -208,7 +197,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "grid", "voltage"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "grid", "voltage"),
|
||||
),
|
||||
NRGkickSensorEntityDescription(
|
||||
key="grid_frequency",
|
||||
@@ -217,7 +206,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "grid", "frequency"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "grid", "frequency"),
|
||||
),
|
||||
# INFO - Network
|
||||
NRGkickSensorEntityDescription(
|
||||
@@ -225,7 +214,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
translation_key="network_ssid",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "network", "ssid"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "network", "ssid"),
|
||||
),
|
||||
NRGkickSensorEntityDescription(
|
||||
key="network_rssi",
|
||||
@@ -234,7 +223,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "network", "rssi"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "network", "rssi"),
|
||||
),
|
||||
# INFO - Cellular (optional, only if cellular module is available)
|
||||
NRGkickSensorEntityDescription(
|
||||
@@ -246,7 +235,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_registry_enabled_default=False,
|
||||
requires_sim_module=True,
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(StateType, _get_nested_dict_value(data.info, "cellular", "mode")),
|
||||
cast(StateType, get_nested_dict_value(data.info, "cellular", "mode")),
|
||||
CELLULAR_MODE_MAP,
|
||||
),
|
||||
),
|
||||
@@ -259,7 +248,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
requires_sim_module=True,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "cellular", "rssi"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "cellular", "rssi"),
|
||||
),
|
||||
NRGkickSensorEntityDescription(
|
||||
key="cellular_operator",
|
||||
@@ -267,7 +256,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
requires_sim_module=True,
|
||||
value_fn=lambda data: _get_nested_dict_value(data.info, "cellular", "operator"),
|
||||
value_fn=lambda data: get_nested_dict_value(data.info, "cellular", "operator"),
|
||||
),
|
||||
# VALUES - Energy
|
||||
NRGkickSensorEntityDescription(
|
||||
@@ -278,7 +267,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_display_precision=3,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "energy", "total_charged_energy"
|
||||
),
|
||||
),
|
||||
@@ -290,7 +279,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_display_precision=3,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "energy", "charged_energy"
|
||||
),
|
||||
),
|
||||
@@ -302,7 +291,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "charging_voltage"
|
||||
),
|
||||
),
|
||||
@@ -313,7 +302,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "charging_current"
|
||||
),
|
||||
),
|
||||
@@ -326,7 +315,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "grid_frequency"
|
||||
),
|
||||
),
|
||||
@@ -339,7 +328,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "peak_power"
|
||||
),
|
||||
),
|
||||
@@ -350,7 +339,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "total_active_power"
|
||||
),
|
||||
),
|
||||
@@ -362,7 +351,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "total_reactive_power"
|
||||
),
|
||||
),
|
||||
@@ -374,7 +363,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "total_apparent_power"
|
||||
),
|
||||
),
|
||||
@@ -386,7 +375,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "total_power_factor"
|
||||
),
|
||||
),
|
||||
@@ -400,7 +389,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "voltage"
|
||||
),
|
||||
),
|
||||
@@ -411,7 +400,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "current"
|
||||
),
|
||||
),
|
||||
@@ -422,7 +411,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "active_power"
|
||||
),
|
||||
),
|
||||
@@ -434,7 +423,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "reactive_power"
|
||||
),
|
||||
),
|
||||
@@ -446,7 +435,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "apparent_power"
|
||||
),
|
||||
),
|
||||
@@ -458,7 +447,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l1", "power_factor"
|
||||
),
|
||||
),
|
||||
@@ -472,7 +461,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "voltage"
|
||||
),
|
||||
),
|
||||
@@ -483,7 +472,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "current"
|
||||
),
|
||||
),
|
||||
@@ -494,7 +483,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "active_power"
|
||||
),
|
||||
),
|
||||
@@ -506,7 +495,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "reactive_power"
|
||||
),
|
||||
),
|
||||
@@ -518,7 +507,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "apparent_power"
|
||||
),
|
||||
),
|
||||
@@ -530,7 +519,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l2", "power_factor"
|
||||
),
|
||||
),
|
||||
@@ -544,7 +533,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "voltage"
|
||||
),
|
||||
),
|
||||
@@ -555,7 +544,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "current"
|
||||
),
|
||||
),
|
||||
@@ -566,7 +555,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
suggested_display_precision=2,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "active_power"
|
||||
),
|
||||
),
|
||||
@@ -578,7 +567,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "reactive_power"
|
||||
),
|
||||
),
|
||||
@@ -590,7 +579,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "apparent_power"
|
||||
),
|
||||
),
|
||||
@@ -602,7 +591,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "l3", "power_factor"
|
||||
),
|
||||
),
|
||||
@@ -616,7 +605,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
suggested_display_precision=2,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "powerflow", "n", "current"
|
||||
),
|
||||
),
|
||||
@@ -626,7 +615,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
translation_key="charging_rate",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "general", "charging_rate"
|
||||
),
|
||||
),
|
||||
@@ -638,12 +627,12 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
_seconds_to_stable_timestamp(
|
||||
cast(
|
||||
StateType,
|
||||
_get_nested_dict_value(
|
||||
get_nested_dict_value(
|
||||
data.values, "general", "vehicle_connect_time"
|
||||
),
|
||||
)
|
||||
)
|
||||
if _get_nested_dict_value(data.values, "general", "status")
|
||||
if get_nested_dict_value(data.values, "general", "status")
|
||||
!= ChargingStatus.STANDBY
|
||||
else None
|
||||
),
|
||||
@@ -655,7 +644,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
suggested_unit_of_measurement=UnitOfTime.MINUTES,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "general", "vehicle_charging_time"
|
||||
),
|
||||
),
|
||||
@@ -665,7 +654,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=_enum_options_from_mapping(STATUS_MAP),
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(StateType, _get_nested_dict_value(data.values, "general", "status")),
|
||||
cast(StateType, get_nested_dict_value(data.values, "general", "status")),
|
||||
STATUS_MAP,
|
||||
),
|
||||
),
|
||||
@@ -675,7 +664,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
suggested_display_precision=0,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "general", "charge_count"
|
||||
),
|
||||
),
|
||||
@@ -687,7 +676,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(
|
||||
StateType, _get_nested_dict_value(data.values, "general", "rcd_trigger")
|
||||
StateType, get_nested_dict_value(data.values, "general", "rcd_trigger")
|
||||
),
|
||||
RCD_TRIGGER_MAP,
|
||||
),
|
||||
@@ -700,8 +689,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(
|
||||
StateType,
|
||||
_get_nested_dict_value(data.values, "general", "warning_code"),
|
||||
StateType, get_nested_dict_value(data.values, "general", "warning_code")
|
||||
),
|
||||
WARNING_CODE_MAP,
|
||||
),
|
||||
@@ -714,7 +702,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _map_code_to_translation_key(
|
||||
cast(
|
||||
StateType, _get_nested_dict_value(data.values, "general", "error_code")
|
||||
StateType, get_nested_dict_value(data.values, "general", "error_code")
|
||||
),
|
||||
ERROR_CODE_MAP,
|
||||
),
|
||||
@@ -727,7 +715,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "housing"
|
||||
),
|
||||
),
|
||||
@@ -738,7 +726,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "connector_l1"
|
||||
),
|
||||
),
|
||||
@@ -749,7 +737,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "connector_l2"
|
||||
),
|
||||
),
|
||||
@@ -760,7 +748,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "connector_l3"
|
||||
),
|
||||
),
|
||||
@@ -771,7 +759,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "domestic_plug_1"
|
||||
),
|
||||
),
|
||||
@@ -782,7 +770,7 @@ SENSORS: tuple[NRGkickSensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda data: _get_nested_dict_value(
|
||||
value_fn=lambda data: get_nested_dict_value(
|
||||
data.values, "temperatures", "domestic_plug_2"
|
||||
),
|
||||
),
|
||||
|
||||
@@ -78,6 +78,11 @@
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"binary_sensor": {
|
||||
"charge_permitted": {
|
||||
"name": "Charge permitted"
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"current_set": {
|
||||
"name": "Charging current"
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"charging_rate": 11.0,
|
||||
"vehicle_connect_time": 100,
|
||||
"vehicle_charging_time": 50,
|
||||
"charge_permitted": 1,
|
||||
"charge_count": 5,
|
||||
"rcd_trigger": 0,
|
||||
"warning_code": 0,
|
||||
|
||||
50
tests/components/nrgkick/snapshots/test_binary_sensor.ambr
Normal file
50
tests/components/nrgkick/snapshots/test_binary_sensor.ambr
Normal file
@@ -0,0 +1,50 @@
|
||||
# serializer version: 1
|
||||
# name: test_binary_sensor_entities[binary_sensor.nrgkick_test_charge_permitted-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.nrgkick_test_charge_permitted',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Charge permitted',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Charge permitted',
|
||||
'platform': 'nrgkick',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charge_permitted',
|
||||
'unique_id': 'TEST123456_charge_permitted',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor_entities[binary_sensor.nrgkick_test_charge_permitted-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'NRGkick Test Charge permitted',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.nrgkick_test_charge_permitted',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
@@ -53,6 +53,7 @@
|
||||
}),
|
||||
'general': dict({
|
||||
'charge_count': 5,
|
||||
'charge_permitted': 1,
|
||||
'charging_rate': 11.0,
|
||||
'error_code': 0,
|
||||
'rcd_trigger': 0,
|
||||
|
||||
45
tests/components/nrgkick/test_binary_sensor.py
Normal file
45
tests/components/nrgkick/test_binary_sensor.py
Normal file
@@ -0,0 +1,45 @@
|
||||
"""Tests for the NRGkick binary sensor platform."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.const import STATE_OFF, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
|
||||
|
||||
async def test_binary_sensor_entities(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_nrgkick_api: AsyncMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test binary sensor entities."""
|
||||
await setup_integration(hass, mock_config_entry, platforms=[Platform.BINARY_SENSOR])
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_charge_permitted_off(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_nrgkick_api: AsyncMock,
|
||||
) -> None:
|
||||
"""Test charge permitted binary sensor when charging is not permitted."""
|
||||
mock_nrgkick_api.get_values.return_value["general"]["charge_permitted"] = 0
|
||||
|
||||
await setup_integration(hass, mock_config_entry, platforms=[Platform.BINARY_SENSOR])
|
||||
|
||||
assert (state := hass.states.get("binary_sensor.nrgkick_test_charge_permitted"))
|
||||
assert state.state == STATE_OFF
|
||||
Reference in New Issue
Block a user