mirror of
https://github.com/home-assistant/core.git
synced 2025-09-10 07:11:37 +02:00
Add IQ Meter Collar and C6 Combiner to enphase_envoy integration (#150649)
This commit is contained in:
@@ -6,7 +6,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from operator import attrgetter
|
||||
|
||||
from pyenphase import EnvoyEncharge, EnvoyEnpower
|
||||
from pyenphase import EnvoyC6CC, EnvoyCollar, EnvoyEncharge, EnvoyEnpower
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
@@ -72,6 +72,42 @@ ENPOWER_SENSORS = (
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class EnvoyCollarBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Describes an Envoy IQ Meter Collar binary sensor entity."""
|
||||
|
||||
value_fn: Callable[[EnvoyCollar], bool]
|
||||
|
||||
|
||||
COLLAR_SENSORS = (
|
||||
EnvoyCollarBinarySensorEntityDescription(
|
||||
key="communicating",
|
||||
translation_key="communicating",
|
||||
device_class=BinarySensorDeviceClass.CONNECTIVITY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=attrgetter("communicating"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class EnvoyC6CCBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Describes an C6 Combiner controller binary sensor entity."""
|
||||
|
||||
value_fn: Callable[[EnvoyC6CC], bool]
|
||||
|
||||
|
||||
C6CC_SENSORS = (
|
||||
EnvoyC6CCBinarySensorEntityDescription(
|
||||
key="communicating",
|
||||
translation_key="communicating",
|
||||
device_class=BinarySensorDeviceClass.CONNECTIVITY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=attrgetter("communicating"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: EnphaseConfigEntry,
|
||||
@@ -95,6 +131,18 @@ async def async_setup_entry(
|
||||
for description in ENPOWER_SENSORS
|
||||
)
|
||||
|
||||
if envoy_data.collar:
|
||||
entities.extend(
|
||||
EnvoyCollarBinarySensorEntity(coordinator, description)
|
||||
for description in COLLAR_SENSORS
|
||||
)
|
||||
|
||||
if envoy_data.c6cc:
|
||||
entities.extend(
|
||||
EnvoyC6CCBinarySensorEntity(coordinator, description)
|
||||
for description in C6CC_SENSORS
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
@@ -168,3 +216,69 @@ class EnvoyEnpowerBinarySensorEntity(EnvoyBaseBinarySensorEntity):
|
||||
enpower = self.data.enpower
|
||||
assert enpower is not None
|
||||
return self.entity_description.value_fn(enpower)
|
||||
|
||||
|
||||
class EnvoyCollarBinarySensorEntity(EnvoyBaseBinarySensorEntity):
|
||||
"""Defines an IQ Meter Collar binary_sensor entity."""
|
||||
|
||||
entity_description: EnvoyCollarBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: EnphaseUpdateCoordinator,
|
||||
description: EnvoyCollarBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Init the Collar base entity."""
|
||||
super().__init__(coordinator, description)
|
||||
collar_data = self.data.collar
|
||||
assert collar_data is not None
|
||||
self._attr_unique_id = f"{collar_data.serial_number}_{description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, collar_data.serial_number)},
|
||||
manufacturer="Enphase",
|
||||
model="IQ Meter Collar",
|
||||
name=f"Collar {collar_data.serial_number}",
|
||||
sw_version=str(collar_data.firmware_version),
|
||||
via_device=(DOMAIN, self.envoy_serial_num),
|
||||
serial_number=collar_data.serial_number,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the state of the Collar binary_sensor."""
|
||||
collar_data = self.data.collar
|
||||
assert collar_data is not None
|
||||
return self.entity_description.value_fn(collar_data)
|
||||
|
||||
|
||||
class EnvoyC6CCBinarySensorEntity(EnvoyBaseBinarySensorEntity):
|
||||
"""Defines an C6 Combiner binary_sensor entity."""
|
||||
|
||||
entity_description: EnvoyC6CCBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: EnphaseUpdateCoordinator,
|
||||
description: EnvoyC6CCBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Init the C6 Combiner base entity."""
|
||||
super().__init__(coordinator, description)
|
||||
c6cc_data = self.data.c6cc
|
||||
assert c6cc_data is not None
|
||||
self._attr_unique_id = f"{c6cc_data.serial_number}_{description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, c6cc_data.serial_number)},
|
||||
manufacturer="Enphase",
|
||||
model="C6 COMBINER CONTROLLER",
|
||||
name=f"C6 Combiner {c6cc_data.serial_number}",
|
||||
sw_version=str(c6cc_data.firmware_version),
|
||||
via_device=(DOMAIN, self.envoy_serial_num),
|
||||
serial_number=c6cc_data.serial_number,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the state of the C6 Combiner binary_sensor."""
|
||||
c6cc_data = self.data.c6cc
|
||||
assert c6cc_data is not None
|
||||
return self.entity_description.value_fn(c6cc_data)
|
||||
|
@@ -12,6 +12,8 @@ from typing import TYPE_CHECKING
|
||||
from pyenphase import (
|
||||
EnvoyACBPower,
|
||||
EnvoyBatteryAggregate,
|
||||
EnvoyC6CC,
|
||||
EnvoyCollar,
|
||||
EnvoyEncharge,
|
||||
EnvoyEnchargeAggregate,
|
||||
EnvoyEnchargePower,
|
||||
@@ -790,6 +792,58 @@ ENPOWER_SENSORS = (
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class EnvoyCollarSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describes an Envoy Collar sensor entity."""
|
||||
|
||||
value_fn: Callable[[EnvoyCollar], datetime.datetime | int | float | str]
|
||||
|
||||
|
||||
COLLAR_SENSORS = (
|
||||
EnvoyCollarSensorEntityDescription(
|
||||
key="temperature",
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
value_fn=attrgetter("temperature"),
|
||||
),
|
||||
EnvoyCollarSensorEntityDescription(
|
||||
key=LAST_REPORTED_KEY,
|
||||
translation_key=LAST_REPORTED_KEY,
|
||||
native_unit_of_measurement=None,
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
value_fn=lambda collar: dt_util.utc_from_timestamp(collar.last_report_date),
|
||||
),
|
||||
EnvoyCollarSensorEntityDescription(
|
||||
key="grid_state",
|
||||
translation_key="grid_status",
|
||||
value_fn=lambda collar: collar.grid_state,
|
||||
),
|
||||
EnvoyCollarSensorEntityDescription(
|
||||
key="mid_state",
|
||||
translation_key="mid_state",
|
||||
value_fn=lambda collar: collar.mid_state,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class EnvoyC6CCSensorEntityDescription(SensorEntityDescription):
|
||||
"""Describes an Envoy C6 Combiner controller sensor entity."""
|
||||
|
||||
value_fn: Callable[[EnvoyC6CC], datetime.datetime]
|
||||
|
||||
|
||||
C6CC_SENSORS = (
|
||||
EnvoyC6CCSensorEntityDescription(
|
||||
key=LAST_REPORTED_KEY,
|
||||
translation_key=LAST_REPORTED_KEY,
|
||||
native_unit_of_measurement=None,
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
value_fn=lambda c6cc: dt_util.utc_from_timestamp(c6cc.last_report_date),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class EnvoyEnchargeAggregateRequiredKeysMixin:
|
||||
"""Mixin for required keys."""
|
||||
@@ -1050,6 +1104,15 @@ async def async_setup_entry(
|
||||
AggregateBatteryEntity(coordinator, description)
|
||||
for description in AGGREGATE_BATTERY_SENSORS
|
||||
)
|
||||
if envoy_data.collar:
|
||||
entities.extend(
|
||||
EnvoyCollarEntity(coordinator, description)
|
||||
for description in COLLAR_SENSORS
|
||||
)
|
||||
if envoy_data.c6cc:
|
||||
entities.extend(
|
||||
EnvoyC6CCEntity(coordinator, description) for description in C6CC_SENSORS
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
@@ -1488,3 +1551,70 @@ class AggregateBatteryEntity(EnvoySystemSensorEntity):
|
||||
battery_aggregate = self.data.battery_aggregate
|
||||
assert battery_aggregate is not None
|
||||
return self.entity_description.value_fn(battery_aggregate)
|
||||
|
||||
|
||||
class EnvoyCollarEntity(EnvoySensorBaseEntity):
|
||||
"""Envoy Collar sensor entity."""
|
||||
|
||||
entity_description: EnvoyCollarSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: EnphaseUpdateCoordinator,
|
||||
description: EnvoyCollarSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize Collar entity."""
|
||||
super().__init__(coordinator, description)
|
||||
collar_data = self.data.collar
|
||||
assert collar_data is not None
|
||||
self._serial_number = collar_data.serial_number
|
||||
self._attr_unique_id = f"{collar_data.serial_number}_{description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, collar_data.serial_number)},
|
||||
manufacturer="Enphase",
|
||||
model="IQ Meter Collar",
|
||||
name=f"Collar {collar_data.serial_number}",
|
||||
sw_version=str(collar_data.firmware_version),
|
||||
via_device=(DOMAIN, self.envoy_serial_num),
|
||||
serial_number=collar_data.serial_number,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> datetime.datetime | int | float | str:
|
||||
"""Return the state of the collar sensors."""
|
||||
collar_data = self.data.collar
|
||||
assert collar_data is not None
|
||||
return self.entity_description.value_fn(collar_data)
|
||||
|
||||
|
||||
class EnvoyC6CCEntity(EnvoySensorBaseEntity):
|
||||
"""Envoy C6CC sensor entity."""
|
||||
|
||||
entity_description: EnvoyC6CCSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: EnphaseUpdateCoordinator,
|
||||
description: EnvoyC6CCSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize Encharge entity."""
|
||||
super().__init__(coordinator, description)
|
||||
c6cc_data = self.data.c6cc
|
||||
assert c6cc_data is not None
|
||||
self._attr_unique_id = f"{c6cc_data.serial_number}_{description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, c6cc_data.serial_number)},
|
||||
manufacturer="Enphase",
|
||||
model="C6 COMBINER CONTROLLER",
|
||||
name=f"C6 Combiner {c6cc_data.serial_number}",
|
||||
sw_version=str(c6cc_data.firmware_version),
|
||||
via_device=(DOMAIN, self.envoy_serial_num),
|
||||
serial_number=c6cc_data.serial_number,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> datetime.datetime:
|
||||
"""Return the state of the c6cc inventory sensors."""
|
||||
c6cc_data = self.data.c6cc
|
||||
assert c6cc_data is not None
|
||||
return self.entity_description.value_fn(c6cc_data)
|
||||
|
@@ -407,6 +407,12 @@
|
||||
},
|
||||
"last_report_duration": {
|
||||
"name": "Last report duration"
|
||||
},
|
||||
"grid_status": {
|
||||
"name": "[%key:component::enphase_envoy::entity::binary_sensor::grid_status::name%]"
|
||||
},
|
||||
"mid_state": {
|
||||
"name": "MID state"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
|
@@ -9,6 +9,8 @@ import multidict
|
||||
from pyenphase import (
|
||||
EnvoyACBPower,
|
||||
EnvoyBatteryAggregate,
|
||||
EnvoyC6CC,
|
||||
EnvoyCollar,
|
||||
EnvoyData,
|
||||
EnvoyEncharge,
|
||||
EnvoyEnchargeAggregate,
|
||||
@@ -260,6 +262,10 @@ def _load_json_2_encharge_enpower_data(
|
||||
)
|
||||
if item := json_fixture["data"].get("battery_aggregate"):
|
||||
mocked_data.battery_aggregate = EnvoyBatteryAggregate(**item)
|
||||
if item := json_fixture["data"].get("collar"):
|
||||
mocked_data.collar = EnvoyCollar(**item)
|
||||
if item := json_fixture["data"].get("c6cc"):
|
||||
mocked_data.c6cc = EnvoyC6CC(**item)
|
||||
|
||||
|
||||
def _load_json_2_raw_data(mocked_data: EnvoyData, json_fixture: dict[str, Any]) -> None:
|
||||
|
@@ -407,6 +407,35 @@
|
||||
"type": "NONE"
|
||||
}
|
||||
},
|
||||
"collar": {
|
||||
"admin_state": 88,
|
||||
"admin_state_str": "ENCMN_MDE_ON_GRID",
|
||||
"firmware_loaded_date": 1752939759,
|
||||
"firmware_version": "3.0.6-D0",
|
||||
"installed_date": 1752939759,
|
||||
"last_report_date": 1752939759,
|
||||
"communicating": true,
|
||||
"mid_state": "close",
|
||||
"grid_state": "on_grid",
|
||||
"part_number": "865-00400-r22",
|
||||
"serial_number": "482520020939",
|
||||
"temperature": 42,
|
||||
"temperature_unit": "C",
|
||||
"control_error": 0,
|
||||
"collar_state": "Installed"
|
||||
},
|
||||
"c6cc": {
|
||||
"admin_state": 82,
|
||||
"admin_state_str": "ENCMN_C6_CC_READY",
|
||||
"firmware_loaded_date": 1752945451,
|
||||
"firmware_version": "0.1.20-D1",
|
||||
"installed_date": 1752945451,
|
||||
"last_report_date": 1752945451,
|
||||
"communicating": true,
|
||||
"part_number": "800-02403-r08",
|
||||
"serial_number": "482523040549",
|
||||
"dmir_version": "0.1.20-D1"
|
||||
},
|
||||
"inverters": {
|
||||
"1": {
|
||||
"serial_number": "1",
|
||||
|
@@ -96,6 +96,104 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor[envoy_metered_batt_relay][binary_sensor.c6_combiner_482523040549_communicating-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': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.c6_combiner_482523040549_communicating',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.CONNECTIVITY: 'connectivity'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Communicating',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'communicating',
|
||||
'unique_id': '482523040549_communicating',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor[envoy_metered_batt_relay][binary_sensor.c6_combiner_482523040549_communicating-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'connectivity',
|
||||
'friendly_name': 'C6 Combiner 482523040549 Communicating',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.c6_combiner_482523040549_communicating',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor[envoy_metered_batt_relay][binary_sensor.collar_482520020939_communicating-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': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.collar_482520020939_communicating',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.CONNECTIVITY: 'connectivity'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Communicating',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'communicating',
|
||||
'unique_id': '482520020939_communicating',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor[envoy_metered_batt_relay][binary_sensor.collar_482520020939_communicating-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'connectivity',
|
||||
'friendly_name': 'Collar 482520020939 Communicating',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.collar_482520020939_communicating',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensor[envoy_metered_batt_relay][binary_sensor.encharge_123456_communicating-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@@ -13947,6 +13947,253 @@
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.c6_combiner_482523040549_last_reported-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.c6_combiner_482523040549_last_reported',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last reported',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_reported',
|
||||
'unique_id': '482523040549_last_reported',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.c6_combiner_482523040549_last_reported-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'C6 Combiner 482523040549 Last reported',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.c6_combiner_482523040549_last_reported',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2025-07-19T17:17:31+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_grid_status-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.collar_482520020939_grid_status',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Grid status',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'grid_status',
|
||||
'unique_id': '482520020939_grid_state',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_grid_status-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Collar 482520020939 Grid status',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.collar_482520020939_grid_status',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on_grid',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_last_reported-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.collar_482520020939_last_reported',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last reported',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_reported',
|
||||
'unique_id': '482520020939_last_reported',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_last_reported-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'Collar 482520020939 Last reported',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.collar_482520020939_last_reported',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2025-07-19T15:42:39+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_mid_state-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.collar_482520020939_mid_state',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'MID state',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'mid_state',
|
||||
'unique_id': '482520020939_mid_state',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_mid_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Collar 482520020939 MID state',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.collar_482520020939_mid_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'close',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_temperature-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.collar_482520020939_temperature',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 1,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'enphase_envoy',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '482520020939_temperature',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.collar_482520020939_temperature-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Collar 482520020939 Temperature',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.collar_482520020939_temperature',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '42',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[envoy_metered_batt_relay][sensor.encharge_123456_apparent_power-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
Reference in New Issue
Block a user