mirror of
https://github.com/home-assistant/core.git
synced 2026-04-20 16:39:02 +02:00
Add Shelly EV charger sensors (#152722)
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"charger_state": {
|
||||
"default": "mdi:ev-station"
|
||||
},
|
||||
"detected_objects": {
|
||||
"default": "mdi:account-group"
|
||||
},
|
||||
|
||||
@@ -33,6 +33,7 @@ from homeassistant.const import (
|
||||
UnitOfPower,
|
||||
UnitOfPressure,
|
||||
UnitOfTemperature,
|
||||
UnitOfTime,
|
||||
UnitOfVolume,
|
||||
UnitOfVolumeFlowRate,
|
||||
)
|
||||
@@ -1489,6 +1490,41 @@ RPC_SENSORS: Final = {
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
role="water_temperature",
|
||||
),
|
||||
"number_work_state": RpcSensorDescription(
|
||||
key="number",
|
||||
sub_key="value",
|
||||
translation_key="charger_state",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=[
|
||||
"charger_charging",
|
||||
"charger_end",
|
||||
"charger_fault",
|
||||
"charger_free",
|
||||
"charger_free_fault",
|
||||
"charger_insert",
|
||||
"charger_pause",
|
||||
"charger_wait",
|
||||
],
|
||||
role="work_state",
|
||||
),
|
||||
"number_energy_charge": RpcSensorDescription(
|
||||
key="number",
|
||||
sub_key="value",
|
||||
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
suggested_display_precision=2,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
role="energy_charge",
|
||||
),
|
||||
"number_time_charge": RpcSensorDescription(
|
||||
key="number",
|
||||
sub_key="value",
|
||||
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||
suggested_display_precision=0,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
role="time_charge",
|
||||
),
|
||||
"presence_num_objects": RpcSensorDescription(
|
||||
key="presence",
|
||||
sub_key="num_objects",
|
||||
|
||||
@@ -141,6 +141,18 @@
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"charger_state": {
|
||||
"state": {
|
||||
"charger_charging": "[%key:common::state::charging%]",
|
||||
"charger_end": "Charge completed",
|
||||
"charger_fault": "Error while charging",
|
||||
"charger_free": "[%key:component::binary_sensor::entity_component::plug::state::off%]",
|
||||
"charger_free_fault": "Can not release plug",
|
||||
"charger_insert": "[%key:component::binary_sensor::entity_component::plug::state::on%]",
|
||||
"charger_pause": "Charging paused by charger",
|
||||
"charger_wait": "Charging paused by vehicle"
|
||||
}
|
||||
},
|
||||
"detected_objects": {
|
||||
"unit_of_measurement": "objects"
|
||||
},
|
||||
|
||||
@@ -157,6 +157,188 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_charger_state-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'charger_charging',
|
||||
'charger_end',
|
||||
'charger_fault',
|
||||
'charger_free',
|
||||
'charger_free_fault',
|
||||
'charger_insert',
|
||||
'charger_pause',
|
||||
'charger_wait',
|
||||
]),
|
||||
}),
|
||||
'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.test_name_charger_state',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Charger state',
|
||||
'platform': 'shelly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'charger_state',
|
||||
'unique_id': '123456789ABC-number:200-number_work_state',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_charger_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Test name Charger state',
|
||||
'options': list([
|
||||
'charger_charging',
|
||||
'charger_end',
|
||||
'charger_fault',
|
||||
'charger_free',
|
||||
'charger_free_fault',
|
||||
'charger_insert',
|
||||
'charger_pause',
|
||||
'charger_wait',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.test_name_charger_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'charger_charging',
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_session_duration-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.test_name_session_duration',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Session duration',
|
||||
'platform': 'shelly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123456789ABC-number:202-number_time_charge',
|
||||
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_session_duration-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Test name Session duration',
|
||||
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.test_name_session_duration',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '60',
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_session_energy-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
'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.test_name_session_energy',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Session energy',
|
||||
'platform': 'shelly',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '123456789ABC-number:201-number_energy_charge',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_shelly_ev_sensors[sensor.test_name_session_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Test name Session energy',
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.test_name_session_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '5.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_rpc_switch_energy_sensors[sensor.test_name_test_switch_0_energy-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -1672,6 +1672,74 @@ async def test_rpc_switch_no_returned_energy_sensor(
|
||||
assert hass.states.get("sensor.test_name_test_switch_0_returned_energy") is None
|
||||
|
||||
|
||||
async def test_rpc_shelly_ev_sensors(
|
||||
hass: HomeAssistant,
|
||||
mock_rpc_device: Mock,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
entity_registry: EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test Shelly EV sensors."""
|
||||
config = deepcopy(mock_rpc_device.config)
|
||||
config["number:200"] = {
|
||||
"name": "Charger state",
|
||||
"meta": {
|
||||
"ui": {
|
||||
"titles": {
|
||||
"charger_charging": "Charging",
|
||||
"charger_end": "End",
|
||||
"charger_fault": "Fault",
|
||||
"charger_free": "Free",
|
||||
"charger_free_fault": "Free fault",
|
||||
"charger_insert": "Insert",
|
||||
"charger_pause": "Pause",
|
||||
"charger_wait": "Wait",
|
||||
},
|
||||
"view": "label",
|
||||
}
|
||||
},
|
||||
"options": [
|
||||
"charger_free",
|
||||
"charger_insert",
|
||||
"charger_free_fault",
|
||||
"charger_wait",
|
||||
"charger_charging",
|
||||
"charger_pause",
|
||||
"charger_end",
|
||||
"charger_fault",
|
||||
],
|
||||
"role": "work_state",
|
||||
}
|
||||
config["number:201"] = {
|
||||
"name": "Session energy",
|
||||
"meta": {"ui": {"unit": "Wh", "view": "label"}},
|
||||
"role": "energy_charge",
|
||||
}
|
||||
config["number:202"] = {
|
||||
"name": "Session duration",
|
||||
"meta": {"ui": {"unit": "min", "view": "label"}},
|
||||
"role": "time_charge",
|
||||
}
|
||||
monkeypatch.setattr(mock_rpc_device, "config", config)
|
||||
|
||||
status = deepcopy(mock_rpc_device.status)
|
||||
status["number:200"] = {"value": "charger_charging"}
|
||||
status["number:201"] = {"value": 5000}
|
||||
status["number:202"] = {"value": 60}
|
||||
monkeypatch.setattr(mock_rpc_device, "status", status)
|
||||
|
||||
await init_integration(hass, 3)
|
||||
|
||||
for entity in ("charger_state", "session_energy", "session_duration"):
|
||||
entity_id = f"{SENSOR_DOMAIN}.test_name_{entity}"
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state == snapshot(name=f"{entity_id}-state")
|
||||
|
||||
entry = entity_registry.async_get(entity_id)
|
||||
assert entry == snapshot(name=f"{entity_id}-entry")
|
||||
|
||||
|
||||
async def test_block_friendly_name_sleeping_sensor(
|
||||
hass: HomeAssistant,
|
||||
mock_block_device: Mock,
|
||||
|
||||
Reference in New Issue
Block a user