Add number platform to Peblar Rocksolid EV Chargers integration (#133739)

This commit is contained in:
Franck Nijhof 2024-12-21 20:16:18 +01:00 committed by GitHub
parent f2df57e230
commit 04276d3523
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 273 additions and 31 deletions

View File

@ -22,13 +22,14 @@ from homeassistant.helpers.aiohttp_client import async_create_clientsession
from .const import DOMAIN from .const import DOMAIN
from .coordinator import ( from .coordinator import (
PeblarConfigEntry, PeblarConfigEntry,
PeblarMeterDataUpdateCoordinator, PeblarDataUpdateCoordinator,
PeblarRuntimeData, PeblarRuntimeData,
PeblarUserConfigurationDataUpdateCoordinator, PeblarUserConfigurationDataUpdateCoordinator,
PeblarVersionDataUpdateCoordinator, PeblarVersionDataUpdateCoordinator,
) )
PLATFORMS = [ PLATFORMS = [
Platform.NUMBER,
Platform.SELECT, Platform.SELECT,
Platform.SENSOR, Platform.SENSOR,
Platform.UPDATE, Platform.UPDATE,
@ -57,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bo
) from err ) from err
# Setup the data coordinators # Setup the data coordinators
meter_coordinator = PeblarMeterDataUpdateCoordinator(hass, entry, api) meter_coordinator = PeblarDataUpdateCoordinator(hass, entry, api)
user_configuration_coordinator = PeblarUserConfigurationDataUpdateCoordinator( user_configuration_coordinator = PeblarUserConfigurationDataUpdateCoordinator(
hass, entry, peblar hass, entry, peblar
) )
@ -70,7 +71,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bo
# Store the runtime data # Store the runtime data
entry.runtime_data = PeblarRuntimeData( entry.runtime_data = PeblarRuntimeData(
meter_coordinator=meter_coordinator, data_coordinator=meter_coordinator,
system_information=system_information, system_information=system_information,
user_configuraton_coordinator=user_configuration_coordinator, user_configuraton_coordinator=user_configuration_coordinator,
version_coordinator=version_coordinator, version_coordinator=version_coordinator,

View File

@ -9,6 +9,7 @@ from peblar import (
Peblar, Peblar,
PeblarApi, PeblarApi,
PeblarError, PeblarError,
PeblarEVInterface,
PeblarMeter, PeblarMeter,
PeblarUserConfiguration, PeblarUserConfiguration,
PeblarVersions, PeblarVersions,
@ -26,7 +27,7 @@ from .const import LOGGER
class PeblarRuntimeData: class PeblarRuntimeData:
"""Class to hold runtime data.""" """Class to hold runtime data."""
meter_coordinator: PeblarMeterDataUpdateCoordinator data_coordinator: PeblarDataUpdateCoordinator
system_information: PeblarSystemInformation system_information: PeblarSystemInformation
user_configuraton_coordinator: PeblarUserConfigurationDataUpdateCoordinator user_configuraton_coordinator: PeblarUserConfigurationDataUpdateCoordinator
version_coordinator: PeblarVersionDataUpdateCoordinator version_coordinator: PeblarVersionDataUpdateCoordinator
@ -43,6 +44,19 @@ class PeblarVersionInformation:
available: PeblarVersions available: PeblarVersions
@dataclass(kw_only=True)
class PeblarData:
"""Class to hold active charging related information of Peblar.
This is data that needs to be polled and updated at a relatively high
frequency in order for this integration to function correctly.
All this data is updated at the same time by a single coordinator.
"""
ev: PeblarEVInterface
meter: PeblarMeter
class PeblarVersionDataUpdateCoordinator( class PeblarVersionDataUpdateCoordinator(
DataUpdateCoordinator[PeblarVersionInformation] DataUpdateCoordinator[PeblarVersionInformation]
): ):
@ -72,8 +86,8 @@ class PeblarVersionDataUpdateCoordinator(
raise UpdateFailed(err) from err raise UpdateFailed(err) from err
class PeblarMeterDataUpdateCoordinator(DataUpdateCoordinator[PeblarMeter]): class PeblarDataUpdateCoordinator(DataUpdateCoordinator[PeblarData]):
"""Class to manage fetching Peblar meter data.""" """Class to manage fetching Peblar active data."""
def __init__( def __init__(
self, hass: HomeAssistant, entry: PeblarConfigEntry, api: PeblarApi self, hass: HomeAssistant, entry: PeblarConfigEntry, api: PeblarApi
@ -88,10 +102,13 @@ class PeblarMeterDataUpdateCoordinator(DataUpdateCoordinator[PeblarMeter]):
update_interval=timedelta(seconds=10), update_interval=timedelta(seconds=10),
) )
async def _async_update_data(self) -> PeblarMeter: async def _async_update_data(self) -> PeblarData:
"""Fetch data from the Peblar device.""" """Fetch data from the Peblar device."""
try: try:
return await self.api.meter() return PeblarData(
ev=await self.api.ev_interface(),
meter=await self.api.meter(),
)
except PeblarError as err: except PeblarError as err:
raise UpdateFailed(err) from err raise UpdateFailed(err) from err

View File

@ -16,7 +16,8 @@ async def async_get_config_entry_diagnostics(
return { return {
"system_information": entry.runtime_data.system_information.to_dict(), "system_information": entry.runtime_data.system_information.to_dict(),
"user_configuration": entry.runtime_data.user_configuraton_coordinator.data.to_dict(), "user_configuration": entry.runtime_data.user_configuraton_coordinator.data.to_dict(),
"meter": entry.runtime_data.meter_coordinator.data.to_dict(), "ev": entry.runtime_data.data_coordinator.data.ev.to_dict(),
"meter": entry.runtime_data.data_coordinator.data.meter.to_dict(),
"versions": { "versions": {
"available": entry.runtime_data.version_coordinator.data.available.to_dict(), "available": entry.runtime_data.version_coordinator.data.available.to_dict(),
"current": entry.runtime_data.version_coordinator.data.current.to_dict(), "current": entry.runtime_data.version_coordinator.data.current.to_dict(),

View File

@ -1,5 +1,10 @@
{ {
"entity": { "entity": {
"number": {
"charge_current_limit": {
"default": "mdi:speedometer"
}
},
"select": { "select": {
"smart_charging": { "smart_charging": {
"default": "mdi:lightning-bolt", "default": "mdi:lightning-bolt",

View File

@ -0,0 +1,104 @@
"""Support for Peblar numbers."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any
from peblar import PeblarApi
from homeassistant.components.number import (
NumberDeviceClass,
NumberEntity,
NumberEntityDescription,
)
from homeassistant.const import EntityCategory, UnitOfElectricCurrent
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import (
PeblarConfigEntry,
PeblarData,
PeblarDataUpdateCoordinator,
PeblarRuntimeData,
)
@dataclass(frozen=True, kw_only=True)
class PeblarNumberEntityDescription(NumberEntityDescription):
"""Describe a Peblar number."""
native_max_value_fn: Callable[[PeblarRuntimeData], int]
set_value_fn: Callable[[PeblarApi, float], Awaitable[Any]]
value_fn: Callable[[PeblarData], int | None]
DESCRIPTIONS = [
PeblarNumberEntityDescription(
key="charge_current_limit",
translation_key="charge_current_limit",
device_class=NumberDeviceClass.CURRENT,
entity_category=EntityCategory.CONFIG,
native_step=1,
native_min_value=6,
native_max_value_fn=lambda x: x.system_information.hardware_max_current,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
set_value_fn=lambda x, v: x.ev_interface(charge_current_limit=int(v) * 1000),
value_fn=lambda x: round(x.ev.charge_current_limit_actual / 1000),
),
]
async def async_setup_entry(
hass: HomeAssistant,
entry: PeblarConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Peblar number based on a config entry."""
async_add_entities(
PeblarNumberEntity(
entry=entry,
description=description,
)
for description in DESCRIPTIONS
)
class PeblarNumberEntity(CoordinatorEntity[PeblarDataUpdateCoordinator], NumberEntity):
"""Defines a Peblar number."""
entity_description: PeblarNumberEntityDescription
_attr_has_entity_name = True
def __init__(
self,
entry: PeblarConfigEntry,
description: PeblarNumberEntityDescription,
) -> None:
"""Initialize the Peblar entity."""
super().__init__(entry.runtime_data.data_coordinator)
self.entity_description = description
self._attr_unique_id = f"{entry.unique_id}_{description.key}"
self._attr_device_info = DeviceInfo(
identifiers={
(DOMAIN, entry.runtime_data.system_information.product_serial_number)
},
)
self._attr_native_max_value = description.native_max_value_fn(
entry.runtime_data
)
@property
def native_value(self) -> int | None:
"""Return the number value."""
return self.entity_description.value_fn(self.coordinator.data)
async def async_set_native_value(self, value: float) -> None:
"""Change to new number value."""
await self.entity_description.set_value_fn(self.coordinator.api, value)
await self.coordinator.async_request_refresh()

View File

@ -5,7 +5,7 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from peblar import PeblarMeter, PeblarUserConfiguration from peblar import PeblarUserConfiguration
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -26,15 +26,15 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import DOMAIN
from .coordinator import PeblarConfigEntry, PeblarMeterDataUpdateCoordinator from .coordinator import PeblarConfigEntry, PeblarData, PeblarDataUpdateCoordinator
@dataclass(frozen=True, kw_only=True) @dataclass(frozen=True, kw_only=True)
class PeblarSensorDescription(SensorEntityDescription): class PeblarSensorDescription(SensorEntityDescription):
"""Describe an Peblar sensor.""" """Describe a Peblar sensor."""
has_fn: Callable[[PeblarUserConfiguration], bool] = lambda _: True has_fn: Callable[[PeblarUserConfiguration], bool] = lambda _: True
value_fn: Callable[[PeblarMeter], int | None] value_fn: Callable[[PeblarData], int | None]
DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = ( DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
@ -48,7 +48,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1, suggested_display_precision=1,
suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_fn=lambda x: x.current_phase_1, value_fn=lambda x: x.meter.current_phase_1,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="current_phase_1", key="current_phase_1",
@ -61,7 +61,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1, suggested_display_precision=1,
suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_fn=lambda x: x.current_phase_1, value_fn=lambda x: x.meter.current_phase_1,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="current_phase_2", key="current_phase_2",
@ -74,7 +74,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1, suggested_display_precision=1,
suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_fn=lambda x: x.current_phase_2, value_fn=lambda x: x.meter.current_phase_2,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="current_phase_3", key="current_phase_3",
@ -87,7 +87,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1, suggested_display_precision=1,
suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE, suggested_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
value_fn=lambda x: x.current_phase_3, value_fn=lambda x: x.meter.current_phase_3,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="energy_session", key="energy_session",
@ -97,7 +97,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2, suggested_display_precision=2,
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda x: x.energy_session, value_fn=lambda x: x.meter.energy_session,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="energy_total", key="energy_total",
@ -108,14 +108,14 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=2, suggested_display_precision=2,
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
value_fn=lambda x: x.energy_total, value_fn=lambda x: x.meter.energy_total,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="power_total", key="power_total",
device_class=SensorDeviceClass.POWER, device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.WATT, native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.power_total, value_fn=lambda x: x.meter.power_total,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="power_phase_1", key="power_phase_1",
@ -126,7 +126,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases >= 2, has_fn=lambda x: x.connected_phases >= 2,
native_unit_of_measurement=UnitOfPower.WATT, native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.power_phase_1, value_fn=lambda x: x.meter.power_phase_1,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="power_phase_2", key="power_phase_2",
@ -137,7 +137,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases >= 2, has_fn=lambda x: x.connected_phases >= 2,
native_unit_of_measurement=UnitOfPower.WATT, native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.power_phase_2, value_fn=lambda x: x.meter.power_phase_2,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="power_phase_3", key="power_phase_3",
@ -148,7 +148,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases == 3, has_fn=lambda x: x.connected_phases == 3,
native_unit_of_measurement=UnitOfPower.WATT, native_unit_of_measurement=UnitOfPower.WATT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.power_phase_3, value_fn=lambda x: x.meter.power_phase_3,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="voltage", key="voltage",
@ -158,7 +158,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases == 1, has_fn=lambda x: x.connected_phases == 1,
native_unit_of_measurement=UnitOfElectricPotential.VOLT, native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.voltage_phase_1, value_fn=lambda x: x.meter.voltage_phase_1,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="voltage_phase_1", key="voltage_phase_1",
@ -169,7 +169,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases >= 2, has_fn=lambda x: x.connected_phases >= 2,
native_unit_of_measurement=UnitOfElectricPotential.VOLT, native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.voltage_phase_1, value_fn=lambda x: x.meter.voltage_phase_1,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="voltage_phase_2", key="voltage_phase_2",
@ -180,7 +180,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases >= 2, has_fn=lambda x: x.connected_phases >= 2,
native_unit_of_measurement=UnitOfElectricPotential.VOLT, native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.voltage_phase_2, value_fn=lambda x: x.meter.voltage_phase_2,
), ),
PeblarSensorDescription( PeblarSensorDescription(
key="voltage_phase_3", key="voltage_phase_3",
@ -191,7 +191,7 @@ DESCRIPTIONS: tuple[PeblarSensorDescription, ...] = (
has_fn=lambda x: x.connected_phases == 3, has_fn=lambda x: x.connected_phases == 3,
native_unit_of_measurement=UnitOfElectricPotential.VOLT, native_unit_of_measurement=UnitOfElectricPotential.VOLT,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.voltage_phase_3, value_fn=lambda x: x.meter.voltage_phase_3,
), ),
) )
@ -209,9 +209,7 @@ async def async_setup_entry(
) )
class PeblarSensorEntity( class PeblarSensorEntity(CoordinatorEntity[PeblarDataUpdateCoordinator], SensorEntity):
CoordinatorEntity[PeblarMeterDataUpdateCoordinator], SensorEntity
):
"""Defines a Peblar sensor.""" """Defines a Peblar sensor."""
entity_description: PeblarSensorDescription entity_description: PeblarSensorDescription
@ -224,7 +222,7 @@ class PeblarSensorEntity(
description: PeblarSensorDescription, description: PeblarSensorDescription,
) -> None: ) -> None:
"""Initialize the Peblar entity.""" """Initialize the Peblar entity."""
super().__init__(entry.runtime_data.meter_coordinator) super().__init__(entry.runtime_data.data_coordinator)
self.entity_description = description self.entity_description = description
self._attr_unique_id = f"{entry.unique_id}_{description.key}" self._attr_unique_id = f"{entry.unique_id}_{description.key}"
self._attr_device_info = DeviceInfo( self._attr_device_info = DeviceInfo(

View File

@ -33,6 +33,11 @@
} }
}, },
"entity": { "entity": {
"number": {
"charge_current_limit": {
"name": "Charge limit"
}
},
"select": { "select": {
"smart_charging": { "smart_charging": {
"name": "Smart charging", "name": "Smart charging",

View File

@ -7,6 +7,7 @@ from contextlib import nullcontext
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from peblar import ( from peblar import (
PeblarEVInterface,
PeblarMeter, PeblarMeter,
PeblarSystemInformation, PeblarSystemInformation,
PeblarUserConfiguration, PeblarUserConfiguration,
@ -64,6 +65,9 @@ def mock_peblar() -> Generator[MagicMock]:
) )
api = peblar.rest_api.return_value api = peblar.rest_api.return_value
api.ev_interface.return_value = PeblarEVInterface.from_json(
load_fixture("ev_interface.json", DOMAIN)
)
api.meter.return_value = PeblarMeter.from_json( api.meter.return_value = PeblarMeter.from_json(
load_fixture("meter.json", DOMAIN) load_fixture("meter.json", DOMAIN)
) )

View File

@ -0,0 +1,7 @@
{
"ChargeCurrentLimit": 16000,
"ChargeCurrentLimitActual": 6000,
"ChargeCurrentLimitSource": "Current limiter",
"CpState": "State C",
"Force1Phase": false
}

View File

@ -1,6 +1,13 @@
# serializer version: 1 # serializer version: 1
# name: test_diagnostics # name: test_diagnostics
dict({ dict({
'ev': dict({
'ChargeCurrentLimit': 16000,
'ChargeCurrentLimitActual': 6000,
'ChargeCurrentLimitSource': 'Current limiter',
'CpState': 'State C',
'Force1Phase': False,
}),
'meter': dict({ 'meter': dict({
'CurrentPhase1': 14242, 'CurrentPhase1': 14242,
'CurrentPhase2': 0, 'CurrentPhase2': 0,

View File

@ -0,0 +1,58 @@
# serializer version: 1
# name: test_entities[number][number.peblar_ev_charger_charge_limit-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 16,
'min': 6,
'mode': <NumberMode.AUTO: 'auto'>,
'step': 1,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'number.peblar_ev_charger_charge_limit',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.CURRENT: 'current'>,
'original_icon': None,
'original_name': 'Charge limit',
'platform': 'peblar',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'charge_current_limit',
'unique_id': '23-45-A4O-MOF_charge_current_limit',
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
})
# ---
# name: test_entities[number][number.peblar_ev_charger_charge_limit-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'current',
'friendly_name': 'Peblar EV Charger Charge limit',
'max': 16,
'min': 6,
'mode': <NumberMode.AUTO: 'auto'>,
'step': 1,
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
}),
'context': <ANY>,
'entity_id': 'number.peblar_ev_charger_charge_limit',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '6',
})
# ---

View File

@ -0,0 +1,35 @@
"""Tests for the Peblar number platform."""
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.peblar.const import DOMAIN
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from tests.common import MockConfigEntry, snapshot_platform
@pytest.mark.parametrize("init_integration", [Platform.NUMBER], indirect=True)
@pytest.mark.usefixtures("init_integration")
async def test_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
device_registry: dr.DeviceRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the number entities."""
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
# Ensure all entities are correctly assigned to the Peblar device
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, "23-45-A4O-MOF")}
)
assert device_entry
entity_entries = er.async_entries_for_config_entry(
entity_registry, mock_config_entry.entry_id
)
for entity_entry in entity_entries:
assert entity_entry.device_id == device_entry.id